diff --git a/configure.ac b/configure.ac --- a/configure.ac +++ b/configure.ac @@ -232,7 +232,7 @@ # # fixme: For what do we need the sys/socket test? AC_CHECK_HEADERS([sys/socket.h sys/select.h unistd.h sys/time.h time.h \ - signal.h]) + signal.h poll.h]) INSERT_SYS_SELECT_H= if test x"$ac_cv_header_sys_select_h" = xyes; then INSERT_SYS_SELECT_H="include " @@ -328,7 +328,7 @@ esac AC_SUBST(INSERT_EXPOSE_RWLOCK_API) -AC_CHECK_FUNCS([select pselect gettimeofday]) +AC_CHECK_FUNCS([select pselect gettimeofday ppoll]) npth_LIBSOCKET config_libs="$config_libs $LIBSOCKET" diff --git a/src/npth.h.in b/src/npth.h.in --- a/src/npth.h.in +++ b/src/npth.h.in @@ -348,6 +348,11 @@ int npth_recvmsg (int fd, struct msghdr *msg, int flags); int npth_sendmsg (int fd, const struct msghdr *msg, int flags); +struct pollfd; +int npth_poll (struct pollfd *fds, unsigned long nfds, int timeout); +int npth_ppoll (struct pollfd *fds, unsigned long nfds, + const struct timespec *timeout, const sigset_t *sigmask); + /* For anything not covered here, you can enter/leave manually at your own risk. */ void npth_unprotect (void); diff --git a/src/npth.c b/src/npth.c --- a/src/npth.c +++ b/src/npth.c @@ -71,6 +71,9 @@ #ifndef HAVE_PSELECT # include #endif +#ifdef HAVE_POLL_H +#include +#endif #include "npth.h" @@ -676,6 +679,69 @@ } +int +npth_poll (struct pollfd *fds, unsigned long nfds, int timeout) +{ + int res; + + ENTER(); + res = poll (fds, (nfds_t)nfds, timeout); + LEAVE(); + return res; +} + + +int +npth_ppoll (struct pollfd *fds, unsigned long nfds, + const struct timespec *timeout, const sigset_t *sigmask) +{ + int res; + + ENTER(); +#ifdef HAVE_PSELECT + res = ppoll (fds, (nfds_t)nfds, timeout, sigmask); +#else /*!HAVE_PSELECT*/ + { +# ifdef __GNUC__ +# warning Using a non race free ppoll emulation. +# endif + + int t; + + if (!timeout) + t = -1; + else if (timeout->tv_nsec >= 0 && timeout->tv_nsec < 1000000000) + t = timeout->tv_sec * 1000 + (timeout->tv_nsec + 999999) / 1000000; + else + { + errno = EINVAL; + res = -1; + goto leave; + } + + if (sigmask) + { + int save_errno; + sigset_t savemask; + + pthread_sigmask (SIG_SETMASK, sigmask, &savemask); + res = poll (fds, (nfds_t)nfds, timeout); + save_errno = errno; + pthread_sigmask (SIG_SETMASK, &savemask, NULL); + errno = save_errno; + } + else + res = poll (fds, (nfds_t)nfds, timeout); + + leave: + ; + } +#endif + LEAVE(); + return res; +} + + ssize_t npth_read(int fd, void *buf, size_t nbytes) {