From 11ec052f76954720524b22d07eb775aa41feffcd Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 16 Jan 2020 14:52:04 -0800 Subject: [PATCH] Avoid calling `poll_oneoff` with zero subscriptions. With https://github.com/WebAssembly/WASI/pull/193 merged, WASI is moving to make `poll_oneoff` with no arguments an error. Even though that's in ephemeral and not yet in a snapshot, we can start to anticipate it in libc: - Remove the `pause` function, since WASI has no signals and thus no way to ever wake it up short of having the host terminate it. - Make `poll` and `pselect` return `ENOTSUP` in the case of having no events to wait for. --- libc-bottom-half/cloudlibc/src/libc/poll/poll.c | 8 +++++++- .../cloudlibc/src/libc/sys/select/pselect.c | 8 +++++++- libc-bottom-half/sources/pause.c | 14 -------------- libc-top-half/musl/include/unistd.h | 2 ++ 4 files changed, 16 insertions(+), 16 deletions(-) delete mode 100644 libc-bottom-half/sources/pause.c diff --git a/libc-bottom-half/cloudlibc/src/libc/poll/poll.c b/libc-bottom-half/cloudlibc/src/libc/poll/poll.c index be76ecd7c..8d7fcaa2b 100644 --- a/libc-bottom-half/cloudlibc/src/libc/poll/poll.c +++ b/libc-bottom-half/cloudlibc/src/libc/poll/poll.c @@ -64,7 +64,13 @@ int poll(struct pollfd *fds, size_t nfds, int timeout) { __wasi_poll_oneoff(subscriptions, events, nevents, &nevents); #endif if (error != 0) { - errno = error; + // WASI's poll requires at least one subscription, or else it returns + // `EINVAL`. Since a `poll` with nothing to wait for is valid in POSIX, + // return `ENOTSUP` to indicate that we don't support that case. + if (nevents == 0) + errno = ENOTSUP; + else + errno = error; return -1; } diff --git a/libc-bottom-half/cloudlibc/src/libc/sys/select/pselect.c b/libc-bottom-half/cloudlibc/src/libc/sys/select/pselect.c index bd1d2fdc0..9ab292aa8 100644 --- a/libc-bottom-half/cloudlibc/src/libc/sys/select/pselect.c +++ b/libc-bottom-half/cloudlibc/src/libc/sys/select/pselect.c @@ -90,7 +90,13 @@ int pselect(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, __wasi_poll_oneoff(subscriptions, events, nevents, &nevents); #endif if (error != 0) { - errno = error; + // WASI's poll requires at least one subscription, or else it returns + // `EINVAL`. Since a `pselect` with nothing to wait for is valid in POSIX, + // return `ENOTSUP` to indicate that we don't support that case. + if (nevents == 0) + errno = ENOTSUP; + else + errno = error; return -1; } diff --git a/libc-bottom-half/sources/pause.c b/libc-bottom-half/sources/pause.c deleted file mode 100644 index 0e3e71250..000000000 --- a/libc-bottom-half/sources/pause.c +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include -#include -#include - -int pause(void) { - size_t n; - __wasi_errno_t error = __wasi_poll_oneoff(0, 0, 0, &n); - if (error != 0) { - errno = error; - return -1; - } - __builtin_trap(); -} diff --git a/libc-top-half/musl/include/unistd.h b/libc-top-half/musl/include/unistd.h index c6fe070bb..e55f638e9 100644 --- a/libc-top-half/musl/include/unistd.h +++ b/libc-top-half/musl/include/unistd.h @@ -128,7 +128,9 @@ char *getcwd(char *, size_t); unsigned alarm(unsigned); #endif unsigned sleep(unsigned); +#ifdef __wasilibc_unmodified_upstream /* WASI has no pause */ int pause(void); +#endif #ifdef __wasilibc_unmodified_upstream /* WASI has no fork/exec */ pid_t fork(void);