From owner-freebsd-hackers@FreeBSD.ORG Mon Mar 31 03:49:35 2008 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D7DF8106566C for ; Mon, 31 Mar 2008 03:49:35 +0000 (UTC) (envelope-from des@des.no) Received: from tim.des.no (tim.des.no [194.63.250.121]) by mx1.freebsd.org (Postfix) with ESMTP id 9475B8FC14 for ; Mon, 31 Mar 2008 03:49:35 +0000 (UTC) (envelope-from des@des.no) Received: from ds4.des.no (des.no [80.203.243.180]) by smtp.des.no (Postfix) with ESMTP id A3956208E; Mon, 31 Mar 2008 05:49:33 +0200 (CEST) From: =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= To: Mel References: <200803301220.39921.fbsd.hackers@rachie.is-a-geek.net> Date: Mon, 31 Mar 2008 05:49:33 +0200 In-Reply-To: <200803301220.39921.fbsd.hackers@rachie.is-a-geek.net> (Mel's message of "Sun\, 30 Mar 2008 12\:20\:38 +0200") Message-ID: <86ve33wo1e.fsf@ds4.des.no> User-Agent: Gnus/5.110006 (No Gnus v0.6) Emacs/23.0.60 (berkeley-unix) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Cc: freebsd-hackers@freebsd.org Subject: Re: Popen and EVFILT_WRITE question X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 31 Mar 2008 03:49:35 -0000 Mel writes: > Hi, > > from reading the manpage on EVFILT_WRITE I thought it would be an easy to= use=20 > 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=20 > 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 i= n=20 > below testcode? > (It doesn't matter if I open the pipe with w+ or r+). > > test.c: > #include > #include > #include > #include > #include > #include > > int main(int argc, char **argv) > { > FILE *proc; > int kq; > struct kevent changes[2], events[2]; > > proc =3D popen("./test.sh", "w+"); > if( -1 =3D=3D (kq =3D 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. Second, you're going to run into buffering issues. 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; 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. DES --=20 Dag-Erling Sm=C3=B8rgrav - des@des.no