Saving stderr output in memory

Dave Decot decot at hpisod2.HP.COM
Tue Mar 13 12:46:51 AEST 1990


Hi.  I am writing a C program, say prog1, that wants to work on System V.3
or later and BSD 4.2 or later.

It wants to run an arbitrary shell command and collect all of that
command's standard output into a buffer in memory, and all of its standard
error output into another buffer.  I need to know the exit status of the
shell command to determine what to do next.  I need to use prog1's 
original standard output and standard error for other purposes later.
I don't know in advance how long either of the standard output or
standard error of the command will be, but it is usually under 80 bytes.
I don't want to use temporary files if at all possible.

I used popen(cmd, "r") to run the command and fgets() to retrieve the
output into a buffer.  I shifted and masked the return value of popen()
to get the exit status of the command, and then call pclose() to wait
for the child process and get rid of the popen() stream.  All of this is
very straightforward.

However, capturing the *standard error* output of the command was harder,
since popen() makes no allowances for that, and I didn't want to use
a temporary file.

Here's what I tried.  Prior to calling popen(), prog1 saves the original
standard error file by duplicating it to another file descriptor, then
creates a pipe, then uses dup2() to duplicate the write end of the pipe
to file descriptor 2 (standard error).  If you follow the above, prog1
is now all ready to read from the read end of the pipe whatever is
written to its own (and any forked child's) standard error output.  So,
as described above, prog1 now calls popen(), reads the standard output
from the popen() stream, and finally calls pclose() to wait for the
child process and destroy the popen() stream.

OK, now.  The problem that arises is that the child process created by
popen() cannot write any more than a pipe-ful bytes to the standard error
pipe, because nobody reads any of it from the other end until after the
child process has terminated and been waited for by the pclose() call.

I thought of keeping the popen() stream open until after reading from
the standard error pipe, but then I cannot determine when I have read all
of the standard error output, since the child process may still be running.

Has anyone any brilliant suggestions?

Dave



More information about the Comp.unix.wizards mailing list