diff options
author | dchagin <dchagin@FreeBSD.org> | 2015-05-24 16:59:25 +0000 |
---|---|---|
committer | dchagin <dchagin@FreeBSD.org> | 2015-05-24 16:59:25 +0000 |
commit | b37f23e513ed48cfa9f92e1078c2724954c2c134 (patch) | |
tree | 6a488882d281c142ecafb1af67fe3b2a7a8f5ab1 /sys/compat/linux | |
parent | 0e434375e13229fc3020d755918f26de9bff0733 (diff) | |
download | FreeBSD-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.c | 53 |
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, <s, 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(<s, args->tsp, sizeof(lts)); + } + + return (error); +} + #if defined(DEBUG) || defined(KTR) /* XXX: can be removed when every ldebug(...) and KTR stuff are removed. */ |