I concur, disentangling untagged, combined STDERR and STDOUT streams is
very difficult: the source process' output buffering will cause
desynchronization between the two streams and the OS's timeslices my be
long enough that you get a lot of output between polls in the parent
process.
Furthermore, if you need perfect correlation between the lines emitted
to the two streams and you can't modify the source program, in the worst
case you need to
- keep the streams separate,
- make sure the source process is not buffering either stream (for
instance if it detects a redirected tty and doesn't flush STDOUT on
every \n),
- have a higher priority on the receiving process,
- to have an OS scheduler that yields the source process's timeslice
when it enters write(), and
- write the receiving to wait for synchronization points (for
instance, newlines) and parse for multiple synchronization points, in
case the child yields in mid-line or emits multiple lines.
The last two items are so that the receiving process can get each chunk
of output when it is sent and before a chunk is sent on the other
stream. Otherwise you will have trouble figuring out exactly which pair
of STDOUT lines a line of STDERR belongs between, and even then you rely
on the OS's scheduler to yield the child process's slice immediately
upon sending.
If you can patch the source process' program, you can try disabling
buffering and having it tag each chunk of output to a single stream, or
having it wait for "user" (i.e. parent process) input after each
significant bit of output are two decent approaches.
- Barrie