svn commit: r196556 - in head/sys: fs/fifofs kern
Jilles Tjoelker
jilles at FreeBSD.org
Tue Aug 25 21:44:15 UTC 2009
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)) {
More information about the svn-src-all
mailing list