Popen and EVFILT_WRITE question
Mel
fbsd.hackers at rachie.is-a-geek.net
Sun Mar 30 03:36:26 PDT 2008
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);
for( ;; )
{
int nev, i;
if( -1 == (nev = kevent(kq, changes, 2, events, 2, NULL)) )
err(EX_OSERR, "kevent");
for( i = 0; i < nev; i++ )
{
char *buf;
if( events[i].filter == EVFILT_READ )
{
if( events[i].flags & EV_ERROR )
{
warn("Event error");
goto END;
}
if( events[i].flags & EV_EOF )
goto END;
buf = malloc(events[i].data);
(void)fread(buf, sizeof(char), events[i].data, proc);
(void)fwrite(buf, sizeof(char), events[i].data, stdout);
free(buf);
}
else if( events[i].filter == EVFILT_WRITE )
{
if( events[i].flags & EV_ERROR )
{
warn("Event error");
goto END;
}
if( events[i].flags & EV_EOF )
goto END;
fprintf(proc, "yes\n");
}
}
}
END:
close(kq);
pclose(proc);
return 0;
}
test.sh:
#!/bin/sh
i=0
while(test $i -lt 3); do
echo sleeping
sleep 1;
i=$((i+1));
done
echo "Do you wanna write? "; read ANSWER
echo $ANSWER
--
Mel
More information about the freebsd-hackers
mailing list