views:

52

answers:

2

Hi, im trying to do this on Android:

Process p = Runtime.getRuntime().exec("sh");

   DataOutputStream out = new DataOutputStream(p.getOutputStream());

   out.writeBytes("something useful\n");

   out.close();

   p.waitFor();

   out = new DataOutputStream(p.getOutputStream());

   out.writeBytes("something useful\n");

   out.close();

   p.waitFor();

The second time I execute out.writeBytes(); , I get a java IOException: "Bad file number". My app has to execute several native programs, but always use the same process. Anyone know why this does not work?

A: 

When you call out.close(), it will automatically call close() on the ouputstream of your process.

Each time you call p.getOutputStream() you get the same OutputStream, on your second use of out, p.getOutputStream() returns an already closed OutputStream.

Basically with your code, you don't really need to close the first DataOutputStream.

Sources :

Colin Hebert
Mh,but I have to wait until the command is executed. =/Without close(); process.waitFor() will block forever.
Fr4gg0r
Just do `out.flush();`
Colin Hebert
Only flush(); will block my Thread forever if I call process.waitFor()
Fr4gg0r
I don't get what you really want to do. `p.waitFor()` waits until the end of process `p`. After `p` has been terminated, you want to send "something useful\n" to `p` ?
Colin Hebert
Yeah, i don't really want to wait until the process has terminated, but until the command has been executed.Another guy just gave me a hint for a workaround.
Fr4gg0r
+1  A: 

Note that the shell is not part of the public SDK (note it is not documented anywhere in the SDK documentation), so this code is in effect relying on private APIs.

Also this puts you outside of the normal application model -- we have no guarantee what will happen to a process you have forked and is not being managed by the platform. It may get killed at any time.

This is also a very inefficient way to do things, compared to doing whatever the command is doing in your own process. And starting a separate process for a command won't let it do anything more than you can, because it still runs as your uid.

So basically... for 99.99% of apps please don't do this. If you are writing a terminal app... well, okay, only geeks are going to care about that anyway, and it isn't going to be of much use since it runs as your uid, but okay. But otherwise, please no. :)

hackbod
yeah, I must admit, I am writing a terminal app. :DI have a working workaroud now:I start the shell process with exec("sh");Then I get the outputstream and add commands via writeBytes(command);After each command i add ("echo DONE");So I wait until i receive the echo and know, the command is executed. :x
Fr4gg0r