popen() with stdout and stderr - reading from stdout or stderr can block forever if there is no data on that stream, but the other one has data. A very simple solution is "bind together" the streams, such that they return (with 0 bytes read) in case there is data only on the other stream. This could be implemented with select/poll/epoll or similar.