aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Chagin <dchagin@FreeBSD.org>2022-04-26 16:35:59 +0000
committerDmitry Chagin <dchagin@FreeBSD.org>2022-06-17 19:34:10 +0000
commit9d4b1eba0ef49798b417a56e70e1c1235aaa7cf3 (patch)
tree764ae1d5ae23cedbbbe3c9e82d2ed77b9b088e48
parent4b4dac6ce80c1879532043f11be5e6dc947be7f3 (diff)
linux(4): Add epoll_pwai2 syscall.
MFC after: 2 weeks (cherry picked from commit e00aad1042e7163865763b42d8d72137eeb9df63)
-rw-r--r--sys/compat/linux/linux_dummy.c1
-rw-r--r--sys/compat/linux/linux_event.c56
2 files changed, 56 insertions, 1 deletions
diff --git a/sys/compat/linux/linux_dummy.c b/sys/compat/linux/linux_dummy.c
index 57360c0d1a00..6bfeeaf5c298 100644
--- a/sys/compat/linux/linux_dummy.c
+++ b/sys/compat/linux/linux_dummy.c
@@ -140,7 +140,6 @@ DUMMY(close_range);
DUMMY(openat2);
DUMMY(pidfd_getfd);
DUMMY(process_madvise);
-DUMMY(epoll_pwait2);
DUMMY(mount_setattr);
/* Linux 4.18: */
DUMMY(io_pgetevents);
diff --git a/sys/compat/linux/linux_event.c b/sys/compat/linux/linux_event.c
index c96159dcdfe3..7d4d3d678e26 100644
--- a/sys/compat/linux/linux_event.c
+++ b/sys/compat/linux/linux_event.c
@@ -535,6 +535,62 @@ linux_epoll_pwait(struct thread *td, struct linux_epoll_pwait_args *args)
args->maxevents, args->timeout, pmask));
}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+int
+linux_epoll_pwait2_64(struct thread *td, struct linux_epoll_pwait2_64_args *args)
+{
+ struct timespec ts, *tsa;
+ struct l_timespec64 lts;
+ sigset_t mask, *pmask;
+ int error;
+
+ error = linux_copyin_sigset(args->mask, sizeof(l_sigset_t),
+ &mask, &pmask);
+ if (error != 0)
+ return (error);
+
+ if (args->timeout) {
+ if ((error = copyin(args->timeout, &lts, sizeof(lts))))
+ return (error);
+ error = linux_to_native_timespec64(&ts, &lts);
+ if (error != 0)
+ return (error);
+ tsa = &ts;
+ } else
+ tsa = NULL;
+
+ return (linux_epoll_wait_ts(td, args->epfd, args->events,
+ args->maxevents, tsa, pmask));
+}
+#else
+int
+linux_epoll_pwait2(struct thread *td, struct linux_epoll_pwait2_args *args)
+{
+ struct timespec ts, *tsa;
+ struct l_timespec lts;
+ sigset_t mask, *pmask;
+ int error;
+
+ error = linux_copyin_sigset(args->mask, sizeof(l_sigset_t),
+ &mask, &pmask);
+ if (error != 0)
+ return (error);
+
+ if (args->timeout) {
+ if ((error = copyin(args->timeout, &lts, sizeof(lts))))
+ return (error);
+ error = linux_to_native_timespec(&ts, &lts);
+ if (error != 0)
+ return (error);
+ tsa = &ts;
+ } else
+ tsa = NULL;
+
+ return (linux_epoll_wait_ts(td, args->epfd, args->events,
+ args->maxevents, tsa, pmask));
+}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
+
static int
epoll_register_kevent(struct thread *td, struct file *epfp, int fd, int filter,
unsigned int flags)