Process Pipes

Danny Arends Danny.Arends at gmail.com
Wed Oct 10 09:40:04 UTC 2018


On Wednesday, 10 October 2018 at 09:16:43 UTC, Gorker wrote:
> On Wednesday, 10 October 2018 at 08:31:36 UTC, Kagamin wrote:
>> Maybe read them with parallelism? 
>> http://dpldocs.info/experimental-docs/std.parallelism.parallel.2.html
>
> thanks, but I'd rather avoid having to use threads just for 
> this reason.
> some other suggestion?

This might be a way to do it under Linux / Posix systems (it 
reads byte by byte), adapted from my web server which uses it to 
read the output from php/perl/cgi scripts:

https://github.com/DannyArends/DaNode/blob/master/danode/process.d

It uses fcntl to make sure the pipe is non-blocking
you can read 1 byte from the stdout pipe, then 1 byte from stderr 
pipe

bool nonblocking(ref File file) {
   version(Posix) {
     return(fcntl(fileno(file.getFP()), F_SETFL, O_NONBLOCK) != 
-1);
   }else{
     return(false);
   }
}

int readpipe(ref Pipe pipe, int verbose = NORMAL){
   File fp = pipe.readEnd;
   try{
     if(fp.isOpen()){
       if(!nonblocking(fp) && verbose >= DEBUG) writeln("[WARN]   
unable to create nonblocking pipe for command");
       return(fgetc(fp.getFP()));
     }
   }catch(Exception e){
     writefln("[WARN]   Exception during readpipe command: %s", 
e.msg);
     fp.close();
   }
   return(EOF);
}


pStdIn = File(inputfile, "r");
pStdOut = pipe();
pStdErr = pipe();
auto cpid = spawnShell(command, pStdIn, pStdOut.writeEnd, 
pStdErr.writeEnd, null);
while(true){
   ch = readpipe(pStdOut);
   outbuffer.put(cast(char)ch);
   ch = readpipe(pStdErr);
   errbuffer.put(cast(char)ch);
}

Hope this works for your usecase


More information about the Digitalmars-d-learn mailing list