This program never terminates:
```
void main(string[] args)
{
import std.process, std.stdio;
"starting".writeln;
auto pipes = pipeProcess(["seq", "13000"], Redirect.stdout); // set me to 12k to work
while(true) {
auto res = tryWait(pipes.pid);
if (res.terminated) break;
}
foreach (c; pipes.stdout.byChunk(100)) {
writeln(cast(string) c);
break;
}
"finished".writeln;
}
```
This is due to pipe's buffer (PIPE_BUF) being exceeded.
http://man7.org/linux/man-pages/man2/pipe.2.html
Of course, the solution is to read from the pipe in the loop, but I feel like this is still something that's very easy to run into.
Not sure whether that's something that can/should be done by the library code, or it should simply be documented better.
Comment #1 by schveiguy — 2018-01-28T18:52:53Z
What is the suggestion here? That tryWait should tell you the read buffer is full? Or that there be a mechanism to check for buffer being full?
I know that pipes can be unintuitive if you haven't set up your ends properly. There are all kinds of cases where you may have a race condition.
The sample above, and the solution you suggest, are both counter-intuitive to me. IMO, the solution is not to worry about the process ending until after you've exhausted the data stream.
In any case, I'm inclined to say that we aren't going to solve this problem by adding any warnings. In fact, I'd discourage having any kind of code based on the buffer being full, as your code, if written correctly, should be pretty immune to buffer sizes.
Piling on top of that -- the pipe itself is abstracted behind a File, which is *also* buffered. extracting meaningful info about the OS's pipe buffer may be a lost cause.
A solution documentation-wise would be to show that pipes are in fact subject to race conditions, and you need to be careful how you code them.
Comment #2 by robert.schadek — 2024-12-01T16:32:16Z