Path: utzoo!attcan!uunet!snorkelwacker!tut.cis.ohio-state.edu!ucbvax!hplabs!hpda!hpcupt1!hpisod2!decot From: decot@hpisod2.HP.COM (Dave Decot) Newsgroups: comp.unix.wizards Subject: Saving stderr output in memory Message-ID: <14020086@hpisod2.HP.COM> Date: 13 Mar 90 02:46:51 GMT Organization: Hewlett Packard, Cupertino Lines: 44 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