interacting with a process with redirected stdin/stdout/stderr

timotheecour timothee.cour2 at gmail.com
Sun Jul 14 23:46:51 PDT 2013


On Monday, 15 July 2013 at 03:49:10 UTC, Timothee Cour wrote:
> I'm trying to interact with a process using std.process and
> redirected stdin/stdout/stderr.
> What would be the recommended way?
>
> For example:
> ----
> auto pipes=pipeShell("myprocess",Redirect.all);
> while(true){
>   pipes.stdin.rawWrite(some_command);
>   foreach (line; pipes.stdout.byLine) {
>     //do something with line
>   }
> }
> ----
>
> This doesn't work because it might block inside 
> pipes.stdout.byLine, as the
> process is requesting more inputs to be written to its stdin 
> before
> outputting more bytes to its stdout.
>
> What's the right approach?
> * fcntl(fd, F_SETFL, O_NONBLOCK); didn't seem to work
> * reading pipes.stdout inside a separate thread?
> In that second case, how to cleanly dispose of a blocked thread 
> when we no
> longer need it?
>
> Any detailed example would help.
> Thanks!



I tried using a separate thread for reading the process' stdout. 
It works, except that sometimes the output is shuffled out of 
order.

Is there anything buggy in this:

----
__gshared string output;

void readBlocking(){
while ((c = fgetc(filepointer)) >= 0)
       output~=cast(char) c;
//NOTE: i can use something more efficient here but that's beside 
the question
}

thread = new Thread(& readBlocking);
output=null;
while(true){
         Thread.sleep(...);
         if(condition) break;
}
//now output is shuffled out of order sometimes
----

Furthermore, is there a standard way to tell when a process is 
waiting for stdin input ? (cf condition above). Currently I'm 
checking whether 'output' was modified within a timeout period T, 
but that's fragile and incurs of penalty of T at least.



More information about the Digitalmars-d-learn mailing list