missing_syscall: add epoll_pwait2() wrapper

This commit is contained in:
Lennart Poettering
2021-02-26 09:21:51 +01:00
parent 8b2620ea8c
commit 420297c9e1
4 changed files with 102 additions and 1 deletions
+43
View File
@@ -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