diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-02-25 16:56:07 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2021-02-26 09:21:51 +0100 |
commit | 420297c9e1bf13757394f7f4dd0f312ba953466d (patch) | |
tree | b70d19d8f2c6aa6c6be68800409662d5223b99d3 /src/basic/missing_syscall.h | |
parent | 8b2620ea8c0fcec96054b4b48625a6289dd23923 (diff) | |
download | systemd-420297c9e1bf13757394f7f4dd0f312ba953466d.tar.gz |
missing_syscall: add epoll_pwait2() wrapper
Diffstat (limited to 'src/basic/missing_syscall.h')
-rw-r--r-- | src/basic/missing_syscall.h | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/basic/missing_syscall.h b/src/basic/missing_syscall.h index 52e9d5dea4..1384324804 100644 --- a/src/basic/missing_syscall.h +++ b/src/basic/missing_syscall.h @@ -5,6 +5,11 @@ #include <errno.h> #include <fcntl.h> +#if HAVE_LINUX_TIME_TYPES_H +/* This header defines __kernel_timespec for us, but is only available since Linux 5.1, hence conditionally + * include this. */ +#include <linux/time_types.h> +#endif #include <signal.h> #include <sys/syscall.h> #include <sys/types.h> @@ -382,3 +387,41 @@ static inline int missing_close_range(int first_fd, int end_fd, unsigned flags) # define close_range missing_close_range #endif + +/* ======================================================================= */ + +#if !HAVE_EPOLL_PWAIT2 + +/* Defined to be equivalent to the kernel's _NSIG_WORDS, i.e. the size of the array of longs that is + * encapsulated by sigset_t. */ +#define KERNEL_NSIG_WORDS (64 / (sizeof(long) * 8)) +#define KERNEL_NSIG_BYTES (KERNEL_NSIG_WORDS * sizeof(long)) + +struct epoll_event; + +static inline int missing_epoll_pwait2( + int fd, + struct epoll_event *events, + int maxevents, + const struct timespec *timeout, + const sigset_t *sigset) { + +# if defined(__NR_epoll_pwait2) && HAVE_LINUX_TIME_TYPES_H + if (timeout) { + /* Convert from userspace timespec to kernel timespec */ + struct __kernel_timespec ts = { + .tv_sec = timeout->tv_sec, + .tv_nsec = timeout->tv_nsec, + }; + + return syscall(__NR_epoll_pwait2, fd, events, maxevents, &ts, sigset, sigset ? KERNEL_NSIG_BYTES : 0); + } else + return syscall(__NR_epoll_pwait2, fd, events, maxevents, NULL, sigset, sigset ? KERNEL_NSIG_BYTES : 0); +# else + errno = ENOSYS; + return -1; +# endif +} + +# define epoll_pwait2 missing_epoll_pwait2 +#endif |