From ecd99cc88c124d604725ae28dfa379cb08924e25 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 28 Sep 2006 19:58:33 +0000 Subject: [PATCH] 2006-09-28 Paolo Bonzini * lib/poll.c (rpl_poll) [__APPLE__]: Use FIONREAD instead of MSG_PEEK. * m4/poll.m4: Look for sys/ioctl.h and sys/filio.h. --- ChangeLog | 5 +++++ lib/poll.c | 51 ++++++++++++++++++++++++++++++++++++++++----------- m4/poll.m4 | 2 +- 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index a96492056..689918637 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2006-09-28 Paolo Bonzini + + * 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 * modules/savewd (Depends-on): Add 'raise'. diff --git a/lib/poll.c b/lib/poll.c index 807088549..78af62d85 100644 --- 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 -#endif +#include "config.h" #include #include "poll.h" @@ -31,6 +29,13 @@ #include #include +#ifdef HAVE_SYS_IOCTL_H +#include +#endif +#ifdef HAVE_SYS_FILIO_H +#include +#endif + #if TIME_WITH_SYS_TIME # include # include @@ -60,7 +65,6 @@ poll (pfd, nfd, timeout) 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 @@ poll (pfd, nfd, timeout) 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; } diff --git a/m4/poll.m4 b/m4/poll.m4 index a3d0ab9d9..eb8806ee5 100644 --- a/m4/poll.m4 +++ b/m4/poll.m4 @@ -68,5 +68,5 @@ This is MacOSX or AIX 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) ]) -- 2.11.0