I have put together some test code to read a child processes stdout,
stderr and to write data to the child's stdin. Moreover, I've managed to
do this using C++ streams.

The input streambuffer class was written by Frank B. Brokken and can be
found in C++ Annotations http://www.icce.rug.nl/documents/cplusplus/

See section 19.4.2.2: Using an n-character buffer

ifdnstreambuf uses the file descriptor returned by pipe (2) so is perfect
for my needs. Indeed, everything works perfectly. Well almost.

Here's the code doing the reading:

        int underflow() {
                if (gptr() < egptr())
                        return *gptr();

                int nread = read(d_fd, d_buffer, d_bufsize);

                if (nread <= 0)
                        return EOF;

                setg(d_buffer, d_buffer, d_buffer + nread);
                return *gptr();
        }

I'm using select (2) to inform me when data becomes available to read.
That works.

The question is, how do I know when to stop reading?
Clearly, if (nread < d_bufsize) then I shouldn't call read (2) again until
select (2) informs me that there's something to read.

However, what should I do if (nread == d_bufsize)? Either I got lucky and
my buffer was exactly the right size to store the data, or there's more
data to read.

The problem is, if I call read (2) again, it'll block awaiting input if
there's none to be had. Ok, so I invoke
        fcntl(d_fd[READ], F_SETFL, O_NONBLOCK);
so that read runs non-blocking. Still no good. An EAGAIN error breaks the
pipe.

I think that I've reached the limits of my knowledge. Can anyone help me
out? Is it possible to re-open the pipe again?

-- 
Angus

Reply via email to