diff options
author | dchagin <dchagin@FreeBSD.org> | 2016-01-09 16:58:57 +0000 |
---|---|---|
committer | dchagin <dchagin@FreeBSD.org> | 2016-01-09 16:58:57 +0000 |
commit | 682bdd605d1e6239366f2c09a908ff48b95fad0c (patch) | |
tree | df5c8301205df5131bff3804be7ab896229ad208 /sys | |
parent | d2d5fcaa34593867706312f21bbe119477508fa1 (diff) | |
download | FreeBSD-src-682bdd605d1e6239366f2c09a908ff48b95fad0c.zip FreeBSD-src-682bdd605d1e6239366f2c09a908ff48b95fad0c.tar.gz |
MFC r283451:
Implement ppoll() system call.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/linux/linux_dummy.c | 1 | ||||
-rw-r--r-- | sys/amd64/linux/syscalls.master | 3 | ||||
-rw-r--r-- | sys/amd64/linux32/linux32_dummy.c | 1 | ||||
-rw-r--r-- | sys/amd64/linux32/syscalls.master | 3 | ||||
-rw-r--r-- | sys/compat/linux/linux_misc.c | 53 | ||||
-rw-r--r-- | sys/i386/linux/linux_dummy.c | 1 | ||||
-rw-r--r-- | sys/i386/linux/syscalls.master | 3 |
7 files changed, 59 insertions, 6 deletions
diff --git a/sys/amd64/linux/linux_dummy.c b/sys/amd64/linux/linux_dummy.c index 11b25b7..80a343e 100644 --- a/sys/amd64/linux/linux_dummy.c +++ b/sys/amd64/linux/linux_dummy.c @@ -92,7 +92,6 @@ DUMMY(inotify_init); DUMMY(inotify_add_watch); DUMMY(inotify_rm_watch); DUMMY(migrate_pages); -DUMMY(ppoll); DUMMY(unshare); DUMMY(splice); DUMMY(tee); diff --git a/sys/amd64/linux/syscalls.master b/sys/amd64/linux/syscalls.master index b359c93..4cab140 100644 --- a/sys/amd64/linux/syscalls.master +++ b/sys/amd64/linux/syscalls.master @@ -456,7 +456,8 @@ 270 AUE_SELECT STD { int linux_pselect6(l_int nfds, \ l_fd_set *readfds, l_fd_set *writefds, l_fd_set *exceptfds, \ struct l_timespec *tsp, l_uintptr_t *sig); } -271 AUE_NULL STD { int linux_ppoll(void); } +271 AUE_POLL STD { int linux_ppoll(struct pollfd *fds, uint32_t nfds, \ + struct l_timespec *tsp, l_sigset_t *sset, l_size_t ssize); } 272 AUE_NULL STD { int linux_unshare(void); } 273 AUE_NULL STD { int linux_set_robust_list(struct linux_robust_list_head *head, \ l_size_t len); } diff --git a/sys/amd64/linux32/linux32_dummy.c b/sys/amd64/linux32/linux32_dummy.c index a8fc745..05e5cef 100644 --- a/sys/amd64/linux32/linux32_dummy.c +++ b/sys/amd64/linux32/linux32_dummy.c @@ -93,7 +93,6 @@ DUMMY(inotify_add_watch); DUMMY(inotify_rm_watch); /* linux 2.6.16: */ DUMMY(migrate_pages); -DUMMY(ppoll); DUMMY(unshare); /* linux 2.6.17: */ DUMMY(splice); diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master index e2d5542..1ed2408 100644 --- a/sys/amd64/linux32/syscalls.master +++ b/sys/amd64/linux32/syscalls.master @@ -514,7 +514,8 @@ 308 AUE_SELECT STD { int linux_pselect6(l_int nfds, l_fd_set *readfds, \ l_fd_set *writefds, l_fd_set *exceptfds, \ struct l_timespec *tsp, l_uintptr_t *sig); } -309 AUE_NULL STD { int linux_ppoll(void); } +309 AUE_POLL STD { int linux_ppoll(struct pollfd *fds, uint32_t nfds, \ + struct l_timespec *tsp, l_sigset_t *sset, l_size_t ssize); } 310 AUE_NULL STD { int linux_unshare(void); } ; linux 2.6.17: 311 AUE_NULL STD { int linux_set_robust_list(struct linux_robust_list_head *head, \ diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index abf59c7..45d6bb2 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -2207,6 +2207,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. */ diff --git a/sys/i386/linux/linux_dummy.c b/sys/i386/linux/linux_dummy.c index d6336ca..543f766 100644 --- a/sys/i386/linux/linux_dummy.c +++ b/sys/i386/linux/linux_dummy.c @@ -89,7 +89,6 @@ DUMMY(inotify_add_watch); DUMMY(inotify_rm_watch); /* linux 2.6.16: */ DUMMY(migrate_pages); -DUMMY(ppoll); DUMMY(unshare); /* linux 2.6.17: */ DUMMY(splice); diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master index 95029f7..563d529 100644 --- a/sys/i386/linux/syscalls.master +++ b/sys/i386/linux/syscalls.master @@ -522,7 +522,8 @@ 308 AUE_SELECT STD { int linux_pselect6(l_int nfds, l_fd_set *readfds, \ l_fd_set *writefds, l_fd_set *exceptfds, \ struct l_timespec *tsp, l_uintptr_t *sig); } -309 AUE_NULL STD { int linux_ppoll(void); } +309 AUE_POLL STD { int linux_ppoll(struct pollfd *fds, uint32_t nfds, \ + struct l_timespec *tsp, l_sigset_t *sset, l_size_t ssize); } 310 AUE_NULL STD { int linux_unshare(void); } ; linux 2.6.17: 311 AUE_NULL STD { int linux_set_robust_list(struct linux_robust_list_head *head, \ |