summaryrefslogtreecommitdiffstats
path: root/sys/compat/linux
diff options
context:
space:
mode:
authordchagin <dchagin@FreeBSD.org>2015-05-24 16:59:25 +0000
committerdchagin <dchagin@FreeBSD.org>2015-05-24 16:59:25 +0000
commitb37f23e513ed48cfa9f92e1078c2724954c2c134 (patch)
tree6a488882d281c142ecafb1af67fe3b2a7a8f5ab1 /sys/compat/linux
parent0e434375e13229fc3020d755918f26de9bff0733 (diff)
downloadFreeBSD-src-b37f23e513ed48cfa9f92e1078c2724954c2c134.zip
FreeBSD-src-b37f23e513ed48cfa9f92e1078c2724954c2c134.tar.gz
Implement ppoll() system call.
Differential Revision: https://reviews.freebsd.org/D1105 Reviewed by: trasz
Diffstat (limited to 'sys/compat/linux')
-rw-r--r--sys/compat/linux/linux_misc.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 21303d7..7a4a683 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -2209,6 +2209,59 @@ linux_pselect6(struct thread *td, struct linux_pselect6_args *args)
return (error);
}
+int
+linux_ppoll(struct thread *td, struct linux_ppoll_args *args)
+{
+ struct timespec ts0, ts1;
+ struct l_timespec lts;
+ struct timespec uts, *tsp;
+ l_sigset_t l_ss;
+ sigset_t *ssp;
+ sigset_t ss;
+ int error;
+
+ if (args->sset != NULL) {
+ if (args->ssize != sizeof(l_ss))
+ return (EINVAL);
+ error = copyin(args->sset, &l_ss, sizeof(l_ss));
+ if (error)
+ return (error);
+ linux_to_bsd_sigset(&l_ss, &ss);
+ ssp = &ss;
+ } else
+ ssp = NULL;
+ if (args->tsp != NULL) {
+ error = copyin(args->tsp, &lts, sizeof(lts));
+ if (error)
+ return (error);
+ uts.tv_sec = lts.tv_sec;
+ uts.tv_nsec = lts.tv_nsec;
+
+ nanotime(&ts0);
+ tsp = &uts;
+ } else
+ tsp = NULL;
+
+ error = kern_poll(td, args->fds, args->nfds, tsp, ssp);
+
+ if (error == 0 && args->tsp != NULL) {
+ if (td->td_retval[0]) {
+ nanotime(&ts1);
+ timespecsub(&ts1, &ts0);
+ timespecsub(&uts, &ts1);
+ if (uts.tv_sec < 0)
+ timespecclear(&uts);
+ } else
+ timespecclear(&uts);
+
+ lts.tv_sec = uts.tv_sec;
+ lts.tv_nsec = uts.tv_nsec;
+ error = copyout(&lts, args->tsp, sizeof(lts));
+ }
+
+ return (error);
+}
+
#if defined(DEBUG) || defined(KTR)
/* XXX: can be removed when every ldebug(...) and KTR stuff are removed. */
OpenPOWER on IntegriCloud