From owner-freebsd-hackers Mon Nov 12 5:29:15 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from alcatraz.iptelecom.net.ua (alcatraz.iptelecom.net.ua [212.9.224.15]) by hub.freebsd.org (Postfix) with ESMTP id 8DB4237B416; Mon, 12 Nov 2001 05:28:52 -0800 (PST) Received: from ipcard.iptcom.net (ipcard.iptcom.net [212.9.224.5]) by alcatraz.iptelecom.net.ua (8.9.3/8.9.3) with ESMTP id PAA16421; Mon, 12 Nov 2001 15:28:49 +0200 (EET) (envelope-from max@vega.com) Received: from vega.vega.com (h178.229.dialup.iptcom.net [212.9.229.178]) by ipcard.iptcom.net (8.9.3/8.9.3) with ESMTP id PAA40190; Mon, 12 Nov 2001 15:28:47 +0200 (EET) (envelope-from max@vega.com) Received: (from max@localhost) by vega.vega.com (8.11.6/8.11.3) id fACDSGt04364; Mon, 12 Nov 2001 15:28:16 +0200 (EET) (envelope-from sobomax@FreeBSD.org) From: Maxim Sobolev Message-Id: <200111121328.fACDSGt04364@vega.vega.com> Subject: kqueue(2) doesn't deliver EV_EOF on pipes [patch] To: jlemon@FreeBSD.org Date: Mon, 12 Nov 2001 15:28:15 +0200 (EET) Cc: current@FreeBSD.org, hackers@FreeBSD.org X-Mailer: ELM [version 2.5 PL5] MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="%--multipart-mixed-boundary-1.4281.1005571695--%" Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG --%--multipart-mixed-boundary-1.4281.1005571695--% Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hi, I've noticed that kqueue(2) doesn't notify reader about EV_EOF condition on pipe. Attached simple test program highlights the problem (confirmed both on 5-CURRENT and 4-STABLE). Also attached is the simple fix. -Maxim --%--multipart-mixed-boundary-1.4281.1005571695--% Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Description: ASCII C program text Content-Disposition: attachment; filename="sys_pipe.c.diff" Index: sys/kern/sys_pipe.c =================================================================== RCS file: /home/ncvs/src/sys/kern/sys_pipe.c,v retrieving revision 1.86 diff -d -u -r1.86 sys_pipe.c --- sys/kern/sys_pipe.c 2001/09/21 22:46:53 1.86 +++ sys/kern/sys_pipe.c 2001/11/12 13:28:05 @@ -1221,6 +1221,7 @@ ppipe->pipe_state |= PIPE_EOF; wakeup(ppipe); + KNOTE(&ppipe->pipe_sel.si_note, 0); ppipe->pipe_peer = NULL; } /* --%--multipart-mixed-boundary-1.4281.1005571695--% Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Description: ASCII C program text Content-Disposition: attachment; filename="testpipe.c" #include #include #include #include #include #include #include void testpassed(int sig) { printf("Test passed\n"); exit(0); } int main(int argc, char **argv) { int kq, pid, ppid, nevents; struct kevent changelist[1]; struct kevent eventlist[1]; int pp[2]; pipe(pp); ppid = getpid(); pid = fork(); switch (pid) { case -1: /* Error */ err(1, "can't fork()"); /* NOTREACHED */ case 0: /* Child */ close(pp[1]); kq = kqueue(); EV_SET(changelist, pp[0], EVFILT_READ, EV_ADD | EV_ENABLE | EV_EOF, \ 0, 0, NULL); kevent(kq, changelist, 1, NULL, 0, NULL); for (;;) { nevents = kevent(kq, NULL, 0, eventlist, 1, NULL); if (nevents > 0 || (eventlist[0].flags & EV_EOF) != 0) { kill(ppid, SIGTERM); exit(0); } } break; default: /* Sever */ close(pp[0]); break; } signal(SIGTERM, testpassed); /* Give child some time to initialise kqueue(2) */ sleep(1); close(pp[1]); /* Give child some time to receive EV_EOF and kill us */ sleep(1); kill(pid, SIGTERM); printf("Test failed\n"); exit(1); } --%--multipart-mixed-boundary-1.4281.1005571695--%-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message