Date: Mon, 12 Nov 2001 15:28:15 +0200 (EET) From: Maxim Sobolev <sobomax@FreeBSD.org> To: jlemon@FreeBSD.org Cc: current@FreeBSD.org, hackers@FreeBSD.org Subject: kqueue(2) doesn't deliver EV_EOF on pipes [patch] Message-ID: <200111121328.fACDSGt04364@vega.vega.com>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
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
[-- Attachment #2 --]
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;
}
/*
[-- Attachment #3 --]
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <err.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
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);
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200111121328.fACDSGt04364>
