Giter Club home page Giter Club logo

Comments (19)

Chainfire avatar Chainfire commented on July 20, 2024

Use addCommand() with OnCommandLineListener rather than OnCommandResultListener to get output without it all being buffered in a large list.

For reading text files, you can use 'cat'. Proper binary reading through libsuperuser is not currently supported well.

from libsuperuser.

AndroidDeveloperLB avatar AndroidDeveloperLB commented on July 20, 2024

Yes, I tried to read a JPG file as if it was a text file, and decode it, but it failed. I was almost sure it won't work, but I wanted to try nevertheless.
Currently, the way I get an InputStream of a protected file, is to change the file access (and save it before, to undo this at the end), make a symlink to it, read from symlink, and then delete the symlink file.

Is it maybe possible to send the content of the file to a non-storage file (meaning in memory) that will be read later? I remember Linux/Unix has some special files that aren't really stored on the storage, but can be read as if they are in the storage.

from libsuperuser.

Chainfire avatar Chainfire commented on July 20, 2024

I would advise against modifying any file (changing its access), this seems like an accident waiting to happen.

You could copy the file to /dev, this will be ram-based, but it's pretty dirty.

libsuperuser should at some point be adapted to support this, but it's not going to happen today, even though it really shouldn't be all that complicated to do.

What you could do in the meantime, is look at the deprecated Shell.run method ( https://github.com/Chainfire/libsuperuser/blob/master/libsuperuser/src/eu/chainfire/libsuperuser/Shell.java#L101 ) and adapt it to your needs. If you read through the method you will see that the STDOUT StreamGobbler consumes process.getInputStream(). You could read from process.getInputStream() yourself instead when executing cat /path/to/binary/file.

While ideally you would use one Shell.Interactive for your root needs and Shell.run performs another su call, this technique does work - I use it myself.

from libsuperuser.

AndroidDeveloperLB avatar AndroidDeveloperLB commented on July 20, 2024

I will check it all out. Thank you.
If you have time, can you please demonstrate any of the methods you've mentioned ?

About future versions of the library, can you please make it work like addCommand, so that it will not need to open a new shell ?

from libsuperuser.

Chainfire avatar Chainfire commented on July 20, 2024

Better late than never, but this is implemented in v1.1.0

from libsuperuser.

AndroidDeveloperLB avatar AndroidDeveloperLB commented on July 20, 2024

OMG I don't remember why I wanted this .
Can you please show how to use this new feature? Maybe by looking I will remember...

from libsuperuser.

Chainfire avatar Chainfire commented on July 20, 2024

See the new README. It's mainly focused on using Shell.Thread but there's also an addCommand variant that works with Shell.Interactive

from libsuperuser.

AndroidDeveloperLB avatar AndroidDeveloperLB commented on July 20, 2024

You mean this part:

    exitCode = Shell.Pool.SU.run("cat /init.rc", new Shell.OnSyncCommandInputStreamListener() {
        @Override
        public void onInputStream(InputStream inputStream) {

But now that I look at what I asked here, is it possible to use this in order to read from files that are protected, such as image files (to preview them without the need to copy them somewhere else) ?

from libsuperuser.

Chainfire avatar Chainfire commented on July 20, 2024

Your original question has two parts.

So that if we call a command that will print a lot, we won't have to get it all in a list that takes a lot of memory.

You use one of the Line callbacks for these.

Also, is it possible to get an InputStream of a protected file?

But now that I look at what I asked here, is it possible to use this in order to read from files that are protected, such as image files (to preview them without the need to copy them somewhere else) ?

The InputStream callbacks pass you an InputStream that reads directly from the command's STDOUT. The command itself runs as root, so if you run "cat /path/to/some/image" you'll get the binary content of said image. You can probably read the InputStream into a Bitmap by using BitmapFactory.decodeStream(inputStream) in the callback, then pass that Bitmap off to an ImageView.

from libsuperuser.

AndroidDeveloperLB avatar AndroidDeveloperLB commented on July 20, 2024

I just tried it now. Once I get the InputStream, it's stuck on the decoding.
See attached screenshot and project.

image

MyApplication.zip

Any idea how to overcome this?

from libsuperuser.

Chainfire avatar Chainfire commented on July 20, 2024

You can try wrapping it in a BufferedInputStream, and call inputStream.close() after reading.

Also wrap in try/except/printStacktrace

from libsuperuser.

AndroidDeveloperLB avatar AndroidDeveloperLB commented on July 20, 2024

OK had a bug related to CountDownLatch (called count instead of countDown), but still, this has the same issue.
It seems that for Shell.Pool.SU.run , even though it has a listener and it runs on a new thread, it blocks the current thread and never finishes.

Look at the screenshot and the new project:

image

I think the bitmap is produced. For some reason I can't debug anymore, so I added logs. I think it was fine before too, as inputStream worked fine with it.
Just the blocking doesn't make sense...

MyApplication.zip

from libsuperuser.

Chainfire avatar Chainfire commented on July 20, 2024

You're not closing the inputStream if there's no exception, that might be it.

The calling thread doesn't continue until the callback is complete, which it will not be, until either the entire stream is read or the inputStream is explicitly closed.

from libsuperuser.

Chainfire avatar Chainfire commented on July 20, 2024

Also, why are you even using a latch? The run() command will not continue until all the callbacks are complete. run() is synchronous, use addCommand() for asynchronous (but looking at the code that's not what you're after, you just want run()).

In addition to the latch not being relevant, the onSTDERR callback can be called more than once, so wouldn't that break your logic too?

from libsuperuser.

AndroidDeveloperLB avatar AndroidDeveloperLB commented on July 20, 2024

The closing of the InputStream was the issue indeed. Now it works fine. Sorry about that. I thought I've put it in "finally" block or outside...
Now it works fine.
About onSTDERR , since it's an error, I should consider it a failure loading, no? Calling it more than once shouldn't be a problem, no? The docs about countDown say:

If the current count equals zero then nothing happens.

from libsuperuser.

Chainfire avatar Chainfire commented on July 20, 2024

Ah in that case it's fine, I rarely use them so I don't know the contract. But it's still a synchronization mechanism, which isn't needed in the code you screenshotted, because run() doesn't return until the command has fully completed (error or not)

from libsuperuser.

AndroidDeveloperLB avatar AndroidDeveloperLB commented on July 20, 2024

Oh, so run is blocking anyway? So no need for the countdown, then, right?
Just need to make sure that the InputStream is closed, right?
Why not auto close it when the function ends, though? There is nothing more that can be done there...
Wouldn't you always have to close it there?

from libsuperuser.

Chainfire avatar Chainfire commented on July 20, 2024

Yes, run(...) is blocking, addCommand(...) non-blocking. This is all spelled out in the README and the docs in the source.

Even though run is blocking, it still runs the callbacks in a dedicated background thread for consistency.

You don't need to close() the inputStream if you guarantee to read it to completion (again, see README). The close() call just reads the stream to the end for you.

It is not done automatically so the stream can be passed off to other threads as well, which can be useful, as long as the user (so the dev using the library, you) keeps in mind that that specific root shell does not continue running until the stream is fully read/closed.

from libsuperuser.

AndroidDeveloperLB avatar AndroidDeveloperLB commented on July 20, 2024

I see. Sorry for that. Usually functions with listeners are running in async manner.

from libsuperuser.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.