Date: Tue, 25 Aug 2009 21:44:14 +0000 (UTC) From: Jilles Tjoelker <jilles@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r196556 - in head/sys: fs/fifofs kern Message-ID: <200908252144.n7PLiETE040556@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jilles Date: Tue Aug 25 21:44:14 2009 New Revision: 196556 URL: http://svn.freebsd.org/changeset/base/196556 Log: Fix poll() on half-closed sockets, while retaining POLLHUP for fifos. This reverts part of r196460, so that sockets only return POLLHUP if both directions are closed/error. Fifos get POLLHUP by closing the unused direction immediately after creating the sockets. The tools/regression/poll/*poll.c tests now pass except for two other things: - if POLLHUP is returned, POLLIN is always returned as well instead of only when there is data left in the buffer to be read - fifo old/new reader distinction does not work the way POSIX specs it Reviewed by: kib, bde Modified: head/sys/fs/fifofs/fifo_vnops.c head/sys/kern/uipc_socket.c Modified: head/sys/fs/fifofs/fifo_vnops.c ============================================================================== --- head/sys/fs/fifofs/fifo_vnops.c Tue Aug 25 20:35:57 2009 (r196555) +++ head/sys/fs/fifofs/fifo_vnops.c Tue Aug 25 21:44:14 2009 (r196556) @@ -193,6 +193,9 @@ fifo_open(ap) goto fail2; fip->fi_writesock = wso; error = soconnect2(wso, rso); + /* Close the direction we do not use, so we can get POLLHUP. */ + if (error == 0) + error = soshutdown(rso, SHUT_WR); if (error) { (void)soclose(wso); fail2: Modified: head/sys/kern/uipc_socket.c ============================================================================== --- head/sys/kern/uipc_socket.c Tue Aug 25 20:35:57 2009 (r196555) +++ head/sys/kern/uipc_socket.c Tue Aug 25 21:44:14 2009 (r196556) @@ -2898,11 +2898,13 @@ sopoll_generic(struct socket *so, int ev if (so->so_oobmark || (so->so_rcv.sb_state & SBS_RCVATMARK)) revents |= events & (POLLPRI | POLLRDBAND); - if ((events & POLLINIGNEOF) == 0) - if (so->so_rcv.sb_state & SBS_CANTRCVMORE) - revents |= POLLHUP; - if (so->so_snd.sb_state & SBS_CANTSENDMORE) - revents |= POLLHUP; + if ((events & POLLINIGNEOF) == 0) { + if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { + revents |= events & (POLLIN | POLLRDNORM); + if (so->so_snd.sb_state & SBS_CANTSENDMORE) + revents |= POLLHUP; + } + } if (revents == 0) { if (events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908252144.n7PLiETE040556>