I want to write small library to guide a child process for a specific needs (not trying to reinvent bicycle here).
My needs includes reading from child stdout
and stderr
. I want to implement this as streams. If I would use simple std::streambuf
descendant that reads directly from pipe on underflow
- then my stdout and stderr streams would block on read when there is no data available. I want to evade this, and so far I have two ideas
Provide a timeouted method for my streams, that checks if there any data. I need only binary interface of streams i.e.
read
andwrite
methods, so method which which returns available data amount is fine enough.But wait - there is already method, with behavior which almost match my desire. std::streambuf::in_avail. What if I'll start background thread which will feed data from pipes to my streambuf? Then I could use standard stream method std::istream::readsome.
Mix of a previous two: provide a method for streams, that will read data from pipe buffer to
streambuf
. Its like flush forstd::istream
. This eliminates need in a background thread.
Personally, I like the second variant better, but I feel, that it have many caveats.
Which variant is better in a terms of code readability, performance and interface usability?
std::istream
objects for child std streams. Once library user callchild_stdout.read(1024)
, he wont gain control until child provide him 1024 bytes. But what if child will hang? Then parent will hang too, and there is no way to break this circle. Only with three separate threads: two to readstdout
andstderr
and one for watchdog to kill child on timeout and thus provide eof to streams. And I want to evade this.std::stream
s aren't suited to do.