diff options
Diffstat (limited to 'openbsd-compat/bsd-poll.c')
-rw-r--r-- | openbsd-compat/bsd-poll.c | 68 |
1 files changed, 40 insertions, 28 deletions
diff --git a/openbsd-compat/bsd-poll.c b/openbsd-compat/bsd-poll.c index c8e6222c0e34..781ee978a651 100644 --- a/openbsd-compat/bsd-poll.c +++ b/openbsd-compat/bsd-poll.c @@ -15,40 +15,45 @@ */ #include "includes.h" -#if !defined(HAVE_POLL) +#if !defined(HAVE_PPOLL) || !defined(HAVE_POLL) || defined(BROKEN_POLL) #include <sys/types.h> #include <sys/time.h> +#ifdef HAVE_SYS_PARAM_H +# include <sys/param.h> +#endif #ifdef HAVE_SYS_SELECT_H # include <sys/select.h> #endif #include <errno.h> +#include <signal.h> #include <stdlib.h> #include <unistd.h> #include "bsd-poll.h" +#if !defined(HAVE_PPOLL) || defined(BROKEN_POLL) /* - * A minimal implementation of poll(2), built on top of select(2). + * A minimal implementation of ppoll(2), built on top of pselect(2). * - * Only supports POLLIN and POLLOUT flags in pfd.events, and POLLIN, POLLOUT - * and POLLERR flags in revents. + * Only supports POLLIN, POLLOUT and POLLPRI flags in pfd.events and + * revents. Notably POLLERR, POLLHUP and POLLNVAL are not supported. * * Supports pfd.fd = -1 meaning "unused" although it's not standard. */ int -poll(struct pollfd *fds, nfds_t nfds, int timeout) +ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmoutp, + const sigset_t *sigmask) { nfds_t i; int saved_errno, ret, fd, maxfd = 0; fd_set *readfds = NULL, *writefds = NULL, *exceptfds = NULL; size_t nmemb; - struct timeval tv, *tvp = NULL; for (i = 0; i < nfds; i++) { fd = fds[i].fd; - if (fd >= FD_SETSIZE) { + if (fd != -1 && fd >= FD_SETSIZE) { errno = EINVAL; return -1; } @@ -69,24 +74,15 @@ poll(struct pollfd *fds, nfds_t nfds, int timeout) fd = fds[i].fd; if (fd == -1) continue; - if (fds[i].events & POLLIN) { + if (fds[i].events & POLLIN) FD_SET(fd, readfds); - FD_SET(fd, exceptfds); - } - if (fds[i].events & POLLOUT) { + if (fds[i].events & POLLOUT) FD_SET(fd, writefds); + if (fds[i].events & POLLPRI) FD_SET(fd, exceptfds); - } } - /* poll timeout is msec, select is timeval (sec + usec) */ - if (timeout >= 0) { - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - tvp = &tv; - } - - ret = select(maxfd + 1, readfds, writefds, exceptfds, tvp); + ret = pselect(maxfd + 1, readfds, writefds, exceptfds, tmoutp, sigmask); saved_errno = errno; /* scan through select results and set poll() flags */ @@ -95,15 +91,12 @@ poll(struct pollfd *fds, nfds_t nfds, int timeout) fds[i].revents = 0; if (fd == -1) continue; - if (FD_ISSET(fd, readfds)) { + if (FD_ISSET(fd, readfds)) fds[i].revents |= POLLIN; - } - if (FD_ISSET(fd, writefds)) { + if (FD_ISSET(fd, writefds)) fds[i].revents |= POLLOUT; - } - if (FD_ISSET(fd, exceptfds)) { - fds[i].revents |= POLLERR; - } + if (FD_ISSET(fd, exceptfds)) + fds[i].revents |= POLLPRI; } out: @@ -114,4 +107,23 @@ out: errno = saved_errno; return ret; } -#endif +#endif /* !HAVE_PPOLL || BROKEN_POLL */ + +#if !defined(HAVE_POLL) || defined(BROKEN_POLL) +int +poll(struct pollfd *fds, nfds_t nfds, int timeout) +{ + struct timespec ts, *tsp = NULL; + + /* poll timeout is msec, ppoll is timespec (sec + nsec) */ + if (timeout >= 0) { + ts.tv_sec = timeout / 1000; + ts.tv_nsec = (timeout % 1000) * 1000000; + tsp = &ts; + } + + return ppoll(fds, nfds, tsp, NULL); +} +#endif /* !HAVE_POLL || BROKEN_POLL */ + +#endif /* !HAVE_PPOLL || !HAVE_POLL || BROKEN_POLL */ |