Re: How does one effect O_NONBLOCK?!
- From: jt@xxxxxxxxxxx (Jens Thoms Toerring)
- Date: 1 Jun 2008 20:13:26 GMT
Edd <edd@xxxxxxxxxxxxxxxx> wrote:
I'm trying to create a wrapper around fork/execve to run an external
process and interact with its standard streams through pipes.
My method: once I've created 3 pipes (for stdout, stderr and stdin)
and forked(), I close() the unneeded ends of the pipes in both the
child and parent processes and then dup2() the 3 descriptors into the
corresponding ends of the pipes in the child before execve()-ing.
In the parent I set up a loop in which select() is called to deal with
the 3 pipes "simultaneously".
I can read stuff that the child is writing to its stdout and stderr
fine, but I'm having trouble detecting when I should pump stuff down
the stdin pipe.
The following is a sketch of my select()-loop, showing stdin related
stuff only:
If I understand it correctly with "stdin stuff" you mean the write
end side of the pipe that's connected to stdin of the child process.
Correct?
fd_set s;
FD_ZERO(&s); FD_SET(fd, &s); /* fd is the write end of the stdin
pipe */
while (select(fd + 1, NULL, &s, NULL, NULL) > 0)
{
if (FD_ISSET(fd, &s))
{
/*
code to read from parent stdin and pump it to the child
...
*/
}
/*
Some other checks, eventually leading to a break statement
...
*/
FD_ZERO(&s); FD_SET(fd, &s);
}
The FD_ISSET() check inside the loop yields a positive result each
time, rather than when the child is asking for input.
As long as the child hasn't closed its stdin and there is still
room in the pipe you can write without blocking, so select()
returns true for that file descriptor. If you want to know the
exact moment the child is doing a blocking read() (if it does
that at all, see below) then I guess there's no way to do that.
What the parent "sees" is a file-like pipe, into which it can
write without blocking until the pipe's buffer is full.
I have no idea what the child does, but it also might call
select(), waiting for input from the parent to become ready
for reading. In that case it would never even call read()
until you already have written something to it's stdin.
So I am a bit confused what exactly you want to achieve. Is
it really a problem if you send something to the child and it
isn't blocked in calling read()? At least I can't see that
from your program. Can you perhaps try to describe a bit more
about what you want to do and not just how you plan to do it?
I keep seeing
the term "non-blocking" mentioned in relation to this, but I'm unsure
how to set this up. O_NONBLOCK and fcntl() are somewhere in the mix, I
believe. I'm going cross-eyed reading man-pages and Googling!
Hopefully somebody can put me out of my misery with a little bit of
example code or something? :)
I don't think setting file descriptors in the parent to non-
blocking would help at all. You call select() before you try
to read or write, so neither read() or write() will block.
Thus setting the file descriptors non-blocking doesn't make
much sense IMHO.
As far as I can see there might be a rather different problem
that's going to bother you. Since you obviously intend to run
arbitrary programs as the child process you may find that
a lot of them won't react as you may assume. By redirecting
the stdout of the child to a pipe and if it uses the normal
C standard output functions (printf() etc. or their C++ equi-
valents) their output will not appear in a line-by-line
fashion anymore like it happens when you run a program from a
terminal but instead the output will come in in large chunks.
That's because the output functions normally do buffering,
storing a line-length of output when writing to a terminal
but using the whole available buffer when writing to a file.
And a pipe looks like a file and not like a terminal. So you
may have to use a pseudo-terminal between the parent and the
child process in order to make the child process believe it's
writing to a terminal and not a file...
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@xxxxxxxxxxx
\__________________________ http://toerring.de
.
- Follow-Ups:
- Re: How does one effect O_NONBLOCK?!
- From: Edd
- Re: How does one effect O_NONBLOCK?!
- References:
- How does one effect O_NONBLOCK?!
- From: Edd
- How does one effect O_NONBLOCK?!
- Prev by Date: How does one effect O_NONBLOCK?!
- Next by Date: Re: How does one effect O_NONBLOCK?!
- Previous by thread: How does one effect O_NONBLOCK?!
- Next by thread: Re: How does one effect O_NONBLOCK?!
- Index(es):
Relevant Pages
|