From owner-freebsd-hackers@FreeBSD.ORG Mon Mar 31 19:46:02 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 62EE4106566C for ; Mon, 31 Mar 2008 19:46:02 +0000 (UTC) (envelope-from fbsd.hackers@rachie.is-a-geek.net) Received: from snoogles.rachie.is-a-geek.net (rachie.is-a-geek.net [66.230.99.27]) by mx1.freebsd.org (Postfix) with ESMTP id 2FF448FC15 for ; Mon, 31 Mar 2008 19:46:02 +0000 (UTC) (envelope-from fbsd.hackers@rachie.is-a-geek.net) Received: from localhost (localhost [127.0.0.1]) by snoogles.rachie.is-a-geek.net (Postfix) with ESMTP id 1DD8E1CC91; Mon, 31 Mar 2008 11:46:01 -0800 (AKDT) From: Mel To: Dag-Erling =?utf-8?q?Sm=C3=B8rgrav?= Date: Mon, 31 Mar 2008 21:45:38 +0200 User-Agent: KMail/1.9.7 References: <200803301220.39921.fbsd.hackers@rachie.is-a-geek.net> <86ve33wo1e.fsf@ds4.des.no> In-Reply-To: <86ve33wo1e.fsf@ds4.des.no> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Message-Id: <200803312145.39372.fbsd.hackers@rachie.is-a-geek.net> 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 19:46:02 -0000 On Monday 31 March 2008 05:49:33 Dag-Erling Sm=C3=B8rgrav wrote: > Mel 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 > > #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. 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"=20 > in Unix; Yeah, I figured that out. Still, the write never fires and that seems like = a=20 bug to me, cause it should fire since there's space in the buffer. In fact,= =20 if you fill the buffer partially before going into the event loop, it does= =20 fire each loop. Plan was to use trickery like fill the buffer up to PIPE_SIZE and when it's= =20 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=20 went with a timeout of 'no input received' instead. > it will either read input or it won't, and what happens when it=20 > 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.= =20 Does it also know it's the end of a pipe and what's on the other end? Cause= =20 it would be a cool filter to have, if you could detect a blocked child as a= =20 parent. It sure is better then arbitrary timeouts (this code will run 'make= =20 install' as a daemon(3) and write 'yes' on those nasty post-install questio= ns=20 in ports). =2D-=20 Mel