changeset 7382:8eedfb060b79

2006-09-28 Paolo Bonzini <bonzini@gnu.org> * lib/poll.c (rpl_poll) [__APPLE__]: Use FIONREAD instead of MSG_PEEK. * m4/poll.m4: Look for sys/ioctl.h and sys/filio.h.
author Paolo Bonzini <bonzini@gnu.org>
date Thu, 28 Sep 2006 19:58:33 +0000
parents 65ffe41adbb5
children 2cdff416776f
files ChangeLog lib/poll.c m4/poll.m4
diffstat 3 files changed, 46 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2006-09-28  Paolo Bonzini  <bonzini@gnu.org>
+
+	* lib/poll.c (rpl_poll) [__APPLE__]: Use FIONREAD instead of MSG_PEEK.
+	* m4/poll.m4: Look for sys/ioctl.h and sys/filio.h.
+
 2006-09-26  Paul Eggert  <eggert@cs.ucla.edu>
 
 	* modules/savewd (Depends-on): Add 'raise'.
--- a/lib/poll.c
+++ b/lib/poll.c
@@ -1,7 +1,7 @@
 /* Emulation for poll(2)
    Contributed by Paolo Bonzini.
 
-   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
 
    This file is part of gnulib.
 
@@ -19,9 +19,7 @@
    with this program; if not, write to the Free Software Foundation,
    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
+#include "config.h"
 
 #include <sys/types.h>
 #include "poll.h"
@@ -31,6 +29,13 @@
 #include <sys/select.h>
 #include <unistd.h>
 
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
+
 #if TIME_WITH_SYS_TIME
 # include <sys/time.h>
 # include <time.h>
@@ -60,7 +65,6 @@
   struct timeval tv, *ptv;
   int maxfd, rc, happened;
   nfds_t i;
-  char data[64];
 
 #ifdef _SC_OPEN_MAX
   if (nfd > sysconf (_SC_OPEN_MAX))
@@ -153,15 +157,40 @@
 	  happened = 0;
 	  if (FD_ISSET (pfd[i].fd, &rfds))
 	    {
-	      /* support for POLLHUP.  An hung up descriptor does not
-		 increase the return value! */
-	      if (recv (pfd[i].fd, data, 64, MSG_PEEK) == -1)
+	      int r;
+	      long avail = -1;
+	      /* support for POLLHUP.  */
+#if defined __MACH__ && defined __APPLE__
+	      /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK for
+		 some kinds of descriptors.  Use FIONREAD to emulate POLLHUP.
+		 It is still not completely POSIX compliant (it does not fully
+		 work on TTYs), but at least it does not delete data!  For other
+		 platforms, we still use MSG_PEEK because it was proved to be
+		 reliable, and I a leery of changing it.  */
+	      do
+		r = ioctl (pfd[i].fd, FIONREAD, &avail);
+	      while (r == -1 && (errno == EAGAIN || errno == EINTR));
+	      if (avail < 0)
+	        avail = 0;
+#else
+	      char data[64];
+	      r = recv (pfd[i].fd, data, 64, MSG_PEEK);
+	      if (r == -1)
 		{
-		  if (errno == ESHUTDOWN || errno == ECONNRESET
-		      || errno == ECONNABORTED || errno == ENETRESET)
-		    pfd[i].revents |= POLLHUP;
+		  avail = (errno == ESHUTDOWN || errno == ECONNRESET ||
+	                   errno == ECONNABORTED || errno == ENETRESET) ? 0 : -1;
+		  errno = 0;
 		}
 	      else
+	        avail = r;
+#endif
+
+	      /* An hung up descriptor does not increase the return value! */
+	      if (avail == 0)
+		pfd[i].revents |= POLLHUP;
+	      else if (avail == -1)
+		pfd[i].revents |= POLLERR;
+	      else
 		happened |= POLLIN | POLLRDNORM;
 	    }
 
--- a/m4/poll.m4
+++ b/m4/poll.m4
@@ -68,5 +68,5 @@
 AC_DEFUN([gl_PREREQ_POLL],
 [
   AC_REQUIRE([AC_HEADER_TIME])
-  AC_CHECK_HEADERS_ONCE(sys/time.h)
+  AC_CHECK_HEADERS_ONCE(sys/time.h sys/ioctl.h sys/filio.h)
 ])