<br><br><div class="gmail_quote">On Tue, Jun 18, 2013 at 3:00 PM, Steven Schveighoffer <span dir="ltr"><<a href="mailto:schveiguy@yahoo.com" target="_blank">schveiguy@yahoo.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">On Tue, 18 Jun 2013 17:41:57 -0400, Timothee Cour <<a href="mailto:thelastmammoth@gmail.com" target="_blank">thelastmammoth@gmail.com</a>> wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I'd like to do the following:<br>
<br>
auto pipes = pipeShell(command, Redirect.stdout | Redirect.stderr);<br>
<br>
while(true){<br>
version(A1)<br>
  string line=pipes.stdout.readln;<br>
version(A2)<br>
  auto line=pipes.stdout.readChunk(<u></u>10);<br>
version(A3)<br>
  auto line=pipes.stdout.readChar();<br>
<br>
  // do something with line<br>
<br>
  if(tryWait(pipes.pid).<u></u>terminated)<br>
    break;<br>
}<br>
<br>
<br>
The problem is that 'string line=pipes.stdout.readln;' seems to block until<br>
the process is terminated, ie if the command is a long running command that<br>
prints a line every 1 second for 10 seconds, this program will wait 10<br>
seconds before starting the processing.<br>
I also tried with rawRead, readf, fgetc but couldn't make it work.<br>
I'm on OSX, if that matters.<br>
<br>
Is there any way to achieve this?<br>
</blockquote>
<br></div></div>
I think the issue is on the child process side.  If you are using buffered I/O you have to flush the buffer.<br></blockquote><div><br></div><div>yes</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

For instance, if the child is using D writeln or C printf, and you are using stdout, then it will only flush after writing 4096 bytes.  You can flush early by calling flush on stdout, or fflush in C.  Note that C will auto-detect if it is an interactive console, and flush via newlines instead.  So running the same program from the console will flush every line!<br>

<br>
Alternatively, you can set the flush policy to flush after every line.  See here:<br>
<br>
<a href="https://developer.apple.com/library/ios/#documentation/System/Conceptual/ManPages_iPhoneOS/man3/setvbuf.3.html" target="_blank">https://developer.apple.com/<u></u>library/ios/#documentation/<u></u>System/Conceptual/ManPages_<u></u>iPhoneOS/man3/setvbuf.3.html</a><br>

<br>
And here:<br>
<br>
<a href="http://dlang.org/phobos/std_stdio.html#.File.setvbuf" target="_blank">http://dlang.org/phobos/std_<u></u>stdio.html#.File.setvbuf</a><br>
<br>
-Steve<br>
</blockquote></div><br><div>Thanks, that does indeed work if I have source code for the child program and I can run 'std.stdio.stdout.setvbuf(buffer, _IOLBF);' right after main. </div><div>However I want to make it work without modifying source of child program.</div>
<div><br></div><div>I tried <a href="http://stackoverflow.com/questions/1401002/trick-an-application-into-thinking-its-stdin-is-interactive-not-a-pipe">http://stackoverflow.com/questions/1401002/trick-an-application-into-thinking-its-stdin-is-interactive-not-a-pipe</a> with script:</div>
<div>auto pipes = pipeShell("script -q /dev/null program", Redirect.stdout | Redirect.stderr);</div><div>that works but has issues : only buffers stdout, not stderr; and I may not want to redirect stderr to stdout; also it won't work in more complex cases, eg if program contains '|' etc, and it requires replacing \r\n by \n.</div>
<div><br></div><div>I tried replacing fork with forkpty inside std.process. That doesn't seem to work: calling isatty(1),isatty(2)   on child process still returns 0. Not sure why.</div><div><br></div><div>I tried calling stdout.setvbuf(buffer, _IOLBF); right after child process creation in std.process (after the fork with case 0); doesn't work either.</div>
<div><br></div><div><br></div>