Date: Mon, 21 Jan 2002 08:50:01 -0800 (PST) From: Maxim Konovalov <maxim@macomnet.ru> To: freebsd-bugs@FreeBSD.org Subject: Re: kern/34020: poll(2) on fifos is broken Message-ID: <200201211650.g0LGo1461271@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/34020; it has been noted by GNATS. From: Maxim Konovalov <maxim@macomnet.ru> To: clemensF <ino-e31cbe40@spotteswoode.dnsalias.org> Cc: FreeBSD-gnats-submit@FreeBSD.ORG Subject: Re: kern/34020: poll(2) on fifos is broken Date: Mon, 21 Jan 2002 19:44:26 +0300 (MSK) Alfred has fixed in -current: http://www.FreeBSD.org/cgi/getmsg.cgi?fetch=395052+397069+/usr/local/www/db/text/2002/cvs-all/20020120.cvs-all Here is the patch for -stable: --- poll.h.orig Mon Jan 21 19:00:01 2002 +++ poll.h Mon Jan 21 19:00:46 2002 @@ -70,6 +70,8 @@ #define POLLATTRIB 0x0400 /* file attributes may have changed */ #define POLLNLINK 0x0800 /* (un)link/rename may have happened */ #define POLLWRITE 0x1000 /* file's contents may have changed */ +/* General FreeBSD extensions (currently only supported for sockets): */ +#define POLLINIGNEOF 0x2000 /* POLLIN, except ignore EOF */ /* * These events are set if they occur regardless of whether they were --- fifo_vnops.c.orig Mon Jan 21 18:40:56 2002 +++ fifo_vnops.c Mon Jan 21 18:46:47 2002 @@ -446,18 +446,41 @@ } */ *ap; { struct file filetmp; - int revents = 0; + int events, revents = 0; - if (ap->a_events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) { + events = ap->a_events & + (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND); + if (events) { + /* + * Tell socket poll to ignore EOF so that we block if + * there is no writer (and no data). + */ + if (events & (POLLIN | POLLRDNORM)) { + events &= ~(POLLIN | POLLRDNORM); + events |= POLLINIGNEOF; + } filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_readsock; if (filetmp.f_data) - revents |= soo_poll(&filetmp, ap->a_events, ap->a_cred, + revents |= soo_poll(&filetmp, events, ap->a_cred, ap->a_p); + + /* + * If POLLIN or POLLRDNORM was requested and POLLINIGNEOF was + * not then convert POLLINIGNEOF back to POLLIN. + */ + events = ap->a_events & (POLLIN | POLLRDNORM | POLLINIGNEOF); + if ((events & (POLLIN | POLLRDNORM)) && + !(events & POLLINIGNEOF) && + (revents & POLLINIGNEOF)) { + revents &= ~POLLINIGNEOF; + revents |= (events & (POLLIN | POLLRDNORM)); + } } - if (ap->a_events & (POLLOUT | POLLWRNORM | POLLWRBAND)) { + events = ap->a_events & (POLLOUT | POLLWRNORM | POLLWRBAND); + if (events) { filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_writesock; if (filetmp.f_data) - revents |= soo_poll(&filetmp, ap->a_events, ap->a_cred, + revents |= soo_poll(&filetmp, events, ap->a_cred, ap->a_p); } return (revents); --- uipc_socket.c.orig Mon Jan 21 19:21:00 2002 +++ uipc_socket.c Mon Jan 21 19:23:00 2002 @@ -1510,6 +1510,11 @@ if (soreadable(so)) revents |= events & (POLLIN | POLLRDNORM); + if (events & POLLINIGNEOF) + if (so->so_rcv.sb_cc >= so->so_rcv.sb_lowat || + !TAILQ_EMPTY(&so->so_comp) || so->so_error) + revents |= POLLINIGNEOF; + if (events & (POLLOUT | POLLWRNORM)) if (sowriteable(so)) revents |= events & (POLLOUT | POLLWRNORM); @@ -1519,7 +1524,9 @@ revents |= events & (POLLPRI | POLLRDBAND); if (revents == 0) { - if (events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) { + if (events & + (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | + POLLRDBAND)) { selrecord(p, &so->so_rcv.sb_sel); so->so_rcv.sb_flags |= SB_SEL; } -- Maxim Konovalov, MAcomnet, Internet-Intranet Dept., system engineer phone: +7 (095) 796-9079, mailto: maxim@macomnet.ru To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200201211650.g0LGo1461271>