From 8577bd357660986eaceacf6f8b0fd6870d2098b7 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Thu, 20 Feb 2003 13:10:05 +0000 Subject: [PATCH] New module poll, from Paolo Bonzini . --- ChangeLog | 8 +++ MODULES.html.sh | 1 + lib/ChangeLog | 5 ++ lib/poll.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/poll_.h | 55 +++++++++++++++++ m4/ChangeLog | 4 ++ m4/poll.m4 | 27 +++++++++ modules/poll | 23 +++++++ 8 files changed, 305 insertions(+) create mode 100644 lib/poll.c create mode 100644 lib/poll_.h create mode 100644 m4/poll.m4 create mode 100644 modules/poll diff --git a/ChangeLog b/ChangeLog index ab546e7e3..45120a157 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2003-02-20 Bruno Haible + + * MODULES.html.sh (func_all_modules): Add poll. + +2003-02-19 Paolo Bonzino + + * modules/poll: New file. + 2003-02-18 Bruno Haible * MODULES.html.sh (func_all_modules): Add mathl. diff --git a/MODULES.html.sh b/MODULES.html.sh index 97206be79..384bbbea4 100755 --- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -1670,6 +1670,7 @@ func_all_modules () func_module mkdir func_module mkstemp func_module mkdtemp + func_module poll func_module stat func_module lstat func_module timespec diff --git a/lib/ChangeLog b/lib/ChangeLog index 553a8a171..f454c4a6a 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,8 @@ +2003-02-19 Paolo Bonzino + + * poll_.h: New file. + * poll.c: New file. + 2003-02-18 Paolo Bonzino * mathl.h: New file. diff --git a/lib/poll.c b/lib/poll.c new file mode 100644 index 000000000..3be55dd84 --- /dev/null +++ b/lib/poll.c @@ -0,0 +1,182 @@ +/* Emulation for poll(2) + Contributed by Paolo Bonzini. + + Copyright 2001, 2002, 2003 Free Software Foundation, Inc. + + This file is part of gnulib. + + gnulib is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1, or (at your option) + any later version. + + gnulib is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with gnulib; see the file COPYING.LIB. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "poll.h" +#include +#include +#include +#include +#include + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#ifndef INFTIM +#define INFTIM (-1) +#endif + +#ifndef EOVERFLOW +#define EOVERFLOW EINVAL +#endif + +int +poll (pfd, nfd, timeout) + struct pollfd *pfd; + nfds_t nfd; + int timeout; +{ + fd_set rfds, wfds, efds; + struct timeval tv, *ptv; + int maxfd, rc, happened; + nfds_t i; + char data[64]; + +#ifdef _SC_OPEN_MAX + if (nfd > sysconf (_SC_OPEN_MAX)) + { + errno = EINVAL; + return -1; + } +#else /* !_SC_OPEN_MAX */ +#ifdef OPEN_MAX + if (nfd > OPEN_MAX) + { + errno = EINVAL; + return -1; + } +#endif /* OPEN_MAX -- else, no check is needed */ +#endif /* !_SC_OPEN_MAX */ + + /* EFAULT is not necessary to implement, but let's do it in the + simplest case. */ + if (!pfd) + { + errno = EFAULT; + return -1; + } + + /* convert timeout number into a timeval structure */ + ptv = &tv; + if (timeout >= 0) + { + /* return immediately or after timeout */ + ptv->tv_sec = timeout / 1000; + ptv->tv_usec = (timeout % 1000) * 1000; + } + else if (timeout == INFTIM) + /* wait forever */ + ptv = NULL; + else + { + errno = EINVAL; + return -1; + } + + /* create fd sets and determine max fd */ + maxfd = -1; + FD_ZERO (&rfds); + FD_ZERO (&wfds); + FD_ZERO (&efds); + for (i = 0; i < nfd; i++) + { + if (pfd[i].fd < 0) + continue; + + if (pfd[i].events & (POLLIN | POLLRDNORM)) + FD_SET (pfd[i].fd, &rfds); + + /* see select(2): "the only exceptional condition detectable + is out-of-band data received on a socket", hence we push + POLLWRBAND events onto wfds instead of efds. */ + if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND)) + FD_SET (pfd[i].fd, &wfds); + if (pfd[i].events & (POLLPRI | POLLRDBAND)) + FD_SET (pfd[i].fd, &efds); + if (pfd[i].fd >= maxfd + && (pfd[i].events & (POLLIN | POLLOUT | POLLPRI + | POLLRDNORM | POLLRDBAND + | POLLWRNORM | POLLWRBAND))) + { + maxfd = pfd[i].fd; + if (maxfd > FD_SETSIZE) + { + errno = EOVERFLOW; + return -1; + } + } + } + + /* examine fd sets */ + rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv); + + /* establish results */ + if (rc > 0) + { + rc = 0; + for (i = 0; i < nfd; i++) + { + pfd[i].revents = 0; + if (pfd[i].fd < 0) + continue; + + 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) + { + if (errno == ESHUTDOWN || errno == ECONNRESET + || errno == ECONNABORTED || errno == ENETRESET) + pfd[i].revents |= POLLHUP; + } + else + happened |= POLLIN | POLLRDNORM; + } + + if (FD_ISSET (pfd[i].fd, &wfds)) + happened |= POLLOUT | POLLWRNORM | POLLWRBAND; + + if (FD_ISSET (pfd[i].fd, &efds)) + happened |= POLLPRI | POLLRDBAND; + + pfd[i].revents |= pfd[i].events & happened; + rc += (happened > 0); + } + } + + return rc; +} diff --git a/lib/poll_.h b/lib/poll_.h new file mode 100644 index 000000000..9c68e4181 --- /dev/null +++ b/lib/poll_.h @@ -0,0 +1,55 @@ +/* Header for poll(2) emulation + Contributed by Paolo Bonzini. + + Copyright 2001, 2002, 2003 Free Software Foundation, Inc. + + This file is part of gnulib. + + gnulib is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1, or (at your option) + any later version. + + gnulib is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with gnulib; see the file COPYING.LIB. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. + */ + +#ifndef GNULIB_POLL_H +#define GNULIB_POLL_H + +/* fake a poll(2) environment */ +#define POLLIN 0x0001 /* any readable data available */ +#define POLLPRI 0x0002 /* OOB/Urgent readable data */ +#define POLLOUT 0x0004 /* file descriptor is writeable */ +#define POLLERR 0x0008 /* some poll error occurred */ +#define POLLHUP 0x0010 /* file descriptor was "hung up" */ +#define POLLNVAL 0x0020 /* requested events "invalid" */ +#define POLLRDNORM 0x0040 +#define POLLRDBAND 0x0080 +#define POLLWRNORM 0x0100 +#define POLLWRBAND 0x0200 + +struct pollfd +{ + int fd; /* which file descriptor to poll */ + short events; /* events we are interested in */ + short revents; /* events found on return */ +}; + +typedef unsigned long nfds_t; + +extern int poll (struct pollfd *pfd, nfds_t nfd, int timeout); + +/* Define INFTIM only if doing so conforms to POSIX. */ +#if !defined (_POSIX_C_SOURCE) && !defined (_XOPEN_SOURCE) +#define INFTIM (-1) +#endif + +#endif diff --git a/m4/ChangeLog b/m4/ChangeLog index 3c9361706..de1b0266d 100644 --- a/m4/ChangeLog +++ b/m4/ChangeLog @@ -1,3 +1,7 @@ +2003-02-19 Paolo Bonzino + + * poll.m4: New file. + 2003-02-18 Paolo Bonzino * mathl.m4: New file. diff --git a/m4/poll.m4 b/m4/poll.m4 new file mode 100644 index 000000000..a23f504f1 --- /dev/null +++ b/m4/poll.m4 @@ -0,0 +1,27 @@ +# poll.m4 serial 1 +dnl Copyright (c) 2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of the program. + +AC_DEFUN([gl_FUNC_POLL], +[ + AC_CHECK_HEADERS(poll.h) + if test x$ac_cv_header_poll_h = xno; then + AC_CONFIG_LINKS([lib/poll.h:lib/poll_.h]) + fi + + AC_REPLACE_FUNCS(poll) + if test $ac_cv_func_poll = no; then + gl_PREREQ_POLL + fi +]) + +# Prerequisites of lib/poll.c. +AC_DEFUN([gl_PREREQ_POLL], +[ + AC_REQUIRE([AC_HEADER_TIME]) + AC_CHECK_HEADERS_ONCE(sys/time.h) +]) diff --git a/modules/poll b/modules/poll new file mode 100644 index 000000000..1d796adc2 --- /dev/null +++ b/modules/poll @@ -0,0 +1,23 @@ +Description: +poll() function: wait for some event on a set of file descriptors. + +Files: +lib/poll.c +lib/poll_.h +m4/poll.m4 + +Depends-on: + +configure.ac: +gl_FUNC_POLL + +Makefile.am: +noinst_HEADERS += poll_.h +DISTCLEANFILES += poll.h + +Include: +#include + +Maintainer: +Paolo Bonzini + -- 2.11.0