Re: Popen and EVFILT_WRITE question



On Monday 31 March 2008 05:49:33 Dag-Erling Smørgrav wrote:
Mel <fbsd.hackers@xxxxxxxxxxxxxxxxxxxx> writes:
Hi,

from reading the manpage on EVFILT_WRITE I thought it would be an easy to
use interface to detect when a program wants input.
So far, that doesn't seem to be the case. Ultimately what I want to do is
pipe all the popen(3)'d output to a logfile and act on any input it
wants.

Could anyone explain to me why I'm never getting the EVFILT_WRITE event
in below testcode?
(It doesn't matter if I open the pipe with w+ or r+).

test.c:
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <sysexits.h>
#include <err.h>
#include <stdio.h>

int main(int argc, char **argv)
{
FILE *proc;
int kq;
struct kevent changes[2], events[2];

proc = popen("./test.sh", "w+");
if( -1 == (kq = kqueue()) )
err(EX_OSERR, "Cannot get a kqueue");

EV_SET(&changes[0], fileno(proc), EVFILT_WRITE, EV_ADD|EV_ENABLE, 0,
0, 0);
EV_SET(&changes[1], fileno(proc), EVFILT_READ, EV_ADD|EV_ENABLE, 0,
0, 0);

This is never going to work.

First, the second kevent overrides the first, because they both have the
same ident.

No, the ident is one part of the uniqueness. The filter type is the second.

Third, an EVFILT_WRITE event will trigger as long as there is space in
the pipe buffer.

There is no such thing as "when a program wants input"
in Unix;

Yeah, I figured that out. Still, the write never fires and that seems like a
bug to me, cause it should fire since there's space in the buffer. In fact,
if you fill the buffer partially before going into the event loop, it does
fire each loop.
Plan was to use trickery like fill the buffer up to PIPE_SIZE and when it's
drained means the child read the input and we should fill it again.
Then I saw the various pipe sizes and didn't think it would be a good idea, so
went with a timeout of 'no input received' instead.

it will either read input or it won't, and what happens when it
reads depends entirely on what the fd it reads from is connected to,
whether it's a slow or fast device, blocking or non-blocking, etc.

The kernel knows that the fd at the end of the pipe is blocked for reading.
Does it also know it's the end of a pipe and what's on the other end? Cause
it would be a cool filter to have, if you could detect a blocked child as a
parent. It sure is better then arbitrary timeouts (this code will run 'make
install' as a daemon(3) and write 'yes' on those nasty post-install questions
in ports).

--
Mel
_______________________________________________
freebsd-hackers@xxxxxxxxxxx mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@xxxxxxxxxxx"



Relevant Pages

  • block on reading a half-filled buffer for ifstream
    ... Only when the buffer becomes full does ... Here's my test code for reading from a pipe: ... the program blocks until BUFF_SIZE chars have ...
    (comp.lang.cpp)
  • Re: non blocking read()
    ... > chunk in the buffer, ... > chunks of data written to one end of a pipe or socket ... > and those returned by reading the other end. ...
    (comp.lang.python)
  • Re: Any fireplace wood stove people here?
    ... Seems he came home from a month travel, and built a fire in a wood stove. ... His is the same as mine, a double walled chimney pipe, about ten inches ... sheeting that I can box in with as far out from the vertical flues as I can? ...
    (alt.home.repair)
  • Re: select()/write() semantics
    ... I am writing about Linux 2.6 and Linux 2.6 does not ... select behaviour on FIFOs was discussed. ... if a buffer was added). ... to a set of pipe buffers. ...
    (comp.os.linux.development.apps)
  • Re: Make pipe data structure be a circular list of pages, rather than
    ... > work on socket locking than on pipe locking. ... > code should conceptually really allow one CPU to empty one pipe buffer ... > This is the main reason why I want to avoid coalescing if possible: ...
    (Linux-Kernel)