Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Aug 2009 12:44:15 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r196460 - head/sys/kern
Message-ID:  <200908231244.n7NCiFgc061095@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sun Aug 23 12:44:15 2009
New Revision: 196460
URL: http://svn.freebsd.org/changeset/base/196460

Log:
  Fix the conformance of poll(2) for sockets after r195423 by
  returning POLLHUP instead of POLLIN for several cases. Now, the
  tools/regression/poll results for FreeBSD are closer to that of the
  Solaris and Linux.
  
  Also, improve the POSIX conformance by explicitely clearing POLLOUT
  when POLLHUP is reported in pollscan(), making the fix global.
  
  Submitted by:	bde
  Reviewed by:	rwatson
  MFC after:	1 week

Modified:
  head/sys/kern/sys_generic.c
  head/sys/kern/uipc_socket.c

Modified: head/sys/kern/sys_generic.c
==============================================================================
--- head/sys/kern/sys_generic.c	Sun Aug 23 12:23:24 2009	(r196459)
+++ head/sys/kern/sys_generic.c	Sun Aug 23 12:44:15 2009	(r196460)
@@ -1228,6 +1228,13 @@ pollscan(td, fds, nfd)
 				selfdalloc(td, fds);
 				fds->revents = fo_poll(fp, fds->events,
 				    td->td_ucred, td);
+				/*
+				 * POSIX requires POLLOUT to be never
+				 * set simultaneously with POLLHUP.
+				 */
+				if ((fds->revents & POLLHUP) != 0)
+					fds->revents &= ~POLLOUT;
+
 				if (fds->revents != 0)
 					n++;
 			}

Modified: head/sys/kern/uipc_socket.c
==============================================================================
--- head/sys/kern/uipc_socket.c	Sun Aug 23 12:23:24 2009	(r196459)
+++ head/sys/kern/uipc_socket.c	Sun Aug 23 12:44:15 2009	(r196460)
@@ -2898,13 +2898,11 @@ 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 |= events & (POLLIN | POLLRDNORM);
-			if (so->so_snd.sb_state & SBS_CANTSENDMORE)
-				revents |= POLLHUP;
-		}
-	}
+	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 (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?200908231244.n7NCiFgc061095>