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)) {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to