diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2016-03-21 10:58:20 -0400 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2016-03-21 10:58:31 -0400 |
commit | 0fe32c80063feb75cae18025174342a150e2ba5c (patch) | |
tree | b5919585f559f2492c99792b8f99138fe0656905 | |
parent | 1e521c3cf1687fd17bf8ceec1a7dadb5d003ed1a (diff) |
src/shared/util.c: add fallback for ppoll(), issue #129.
Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | configure.ac | 12 | ||||
-rw-r--r-- | src/shared/util.c | 20 |
3 files changed, 29 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore index 9a1c2b4add..9e04dd33f1 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ Makefile.in aclocal.m4 autom4te.cache +compile config.* configure libtool diff --git a/configure.ac b/configure.ac index 19c4299ebf..19fcdd4ddc 100644 --- a/configure.ac +++ b/configure.ac @@ -64,13 +64,17 @@ AC_C_INLINE AC_TYPE_MODE_T AC_TYPE_PID_T AC_CHECK_MEMBERS([struct stat.st_rdev]) -AC_CHECK_DECLS([getrandom, gettid, name_to_handle_at, accept4, mkostemp, strndupa], [], [], [[#include <sys/types.h> -#include <unistd.h> +AC_CHECK_DECLS([getrandom, gettid, name_to_handle_at, accept4, mkostemp, ppoll, strndupa], [], [], +[[#include <fcntl.h> +#include <linux/random.h> +#include <poll.h> +#include <signal.h> +#include <stdlib.h> #include <string.h> #include <sys/mount.h> -#include <fcntl.h> #include <sys/socket.h> -#include <linux/random.h>]]) +#include <sys/types.h> +#include <unistd.h>]]) AC_CHECK_SIZEOF(pid_t) AC_CHECK_SIZEOF(uid_t) diff --git a/src/shared/util.c b/src/shared/util.c index 88defdc4f2..3f6c1dcde4 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -1091,6 +1091,21 @@ bool nulstr_contains(const char*nulstr, const char *needle) { return false; } + +static inline int ppoll_fallback(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts, const sigset_t *sigmask) { + int ready, timeout; + sigset_t origmask; + + timeout = (timeout_ts == NULL) ? -1 : (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000); + + /* This is racey, but what can we do without ppoll? */ + sigprocmask(SIG_SETMASK, sigmask, &origmask); + ready = poll(fds, nfds, timeout); + sigprocmask(SIG_SETMASK, &origmask, NULL); + + return ready; +} + int fd_wait_for_event(int fd, int event, usec_t t) { struct pollfd pollfd = { @@ -1101,7 +1116,12 @@ int fd_wait_for_event(int fd, int event, usec_t t) { struct timespec ts; int r; +#ifdef HAVE_DECL_PPOLL r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL); +#else + /* Fallback path when ppoll() is unavailable */ + r = ppoll_fallback(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL); +#endif if (r < 0) return -errno; |