diff options
author | dchagin <dchagin@FreeBSD.org> | 2015-05-24 15:06:39 +0000 |
---|---|---|
committer | dchagin <dchagin@FreeBSD.org> | 2015-05-24 15:06:39 +0000 |
commit | 912ea57deb8324ea208d9f68bc1e349253ffc6e1 (patch) | |
tree | 1082aae0d7fd0206be5bd27b13e1eee0981a59d3 /sys | |
parent | 335c9a98ce6e0d62bd72bb7911a15632b69bc914 (diff) | |
download | FreeBSD-src-912ea57deb8324ea208d9f68bc1e349253ffc6e1.zip FreeBSD-src-912ea57deb8324ea208d9f68bc1e349253ffc6e1.tar.gz |
Implement waitid() system call.
Differential Revision: https://reviews.freebsd.org/D1046
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/linux32/linux32_dummy.c | 1 | ||||
-rw-r--r-- | sys/amd64/linux32/syscalls.master | 4 | ||||
-rw-r--r-- | sys/compat/linux/linux_misc.c | 62 | ||||
-rw-r--r-- | sys/compat/linux/linux_misc.h | 6 | ||||
-rw-r--r-- | sys/i386/linux/linux_dummy.c | 1 | ||||
-rw-r--r-- | sys/i386/linux/syscalls.master | 4 |
6 files changed, 74 insertions, 4 deletions
diff --git a/sys/amd64/linux32/linux32_dummy.c b/sys/amd64/linux32/linux32_dummy.c index ecf5168..6d73138 100644 --- a/sys/amd64/linux32/linux32_dummy.c +++ b/sys/amd64/linux32/linux32_dummy.c @@ -84,7 +84,6 @@ DUMMY(mq_timedreceive); DUMMY(mq_notify); DUMMY(mq_getsetattr); DUMMY(kexec_load); -DUMMY(waitid); /* linux 2.6.11: */ DUMMY(add_key); DUMMY(request_key); diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master index 7d3c11b..7fd0d82 100644 --- a/sys/amd64/linux32/syscalls.master +++ b/sys/amd64/linux32/syscalls.master @@ -466,7 +466,9 @@ 281 AUE_NULL STD { int linux_mq_notify(void); } 282 AUE_NULL STD { int linux_mq_getsetattr(void); } 283 AUE_NULL STD { int linux_kexec_load(void); } -284 AUE_NULL STD { int linux_waitid(void); } +284 AUE_WAIT6 STD { int linux_waitid(int idtype, l_pid_t id, \ + l_siginfo_t *info, int options, \ + struct l_rusage *rusage); } 285 AUE_NULL UNIMPL ; linux 2.6.11: 286 AUE_NULL STD { int linux_add_key(void); } diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 1129996..694c853 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -917,6 +917,68 @@ linux_wait4(struct thread *td, struct linux_wait4_args *args) } int +linux_waitid(struct thread *td, struct linux_waitid_args *args) +{ + int status, options, sig; + struct __wrusage wru; + siginfo_t siginfo; + l_siginfo_t lsi; + idtype_t idtype; + struct proc *p; + int error; + + options = 0; + linux_to_bsd_waitopts(args->options, &options); + + if (options & ~(WNOHANG | WNOWAIT | WEXITED | WUNTRACED | WCONTINUED)) + return (EINVAL); + if (!(options & (WEXITED | WUNTRACED | WCONTINUED))) + return (EINVAL); + + switch (args->idtype) { + case LINUX_P_ALL: + idtype = P_ALL; + break; + case LINUX_P_PID: + if (args->id <= 0) + return (EINVAL); + idtype = P_PID; + break; + case LINUX_P_PGID: + if (args->id <= 0) + return (EINVAL); + idtype = P_PGID; + break; + default: + return (EINVAL); + } + + error = kern_wait6(td, idtype, args->id, &status, options, + &wru, &siginfo); + if (error != 0) + return (error); + if (args->rusage != NULL) { + error = linux_copyout_rusage(&wru.wru_children, + args->rusage); + if (error != 0) + return (error); + } + if (args->info != NULL) { + p = td->td_proc; + if (td->td_retval[0] == 0) + bzero(&lsi, sizeof(lsi)); + else { + sig = BSD_TO_LINUX_SIGNAL(siginfo.si_signo); + siginfo_to_lsiginfo(&siginfo, &lsi, sig); + } + error = copyout(&lsi, args->info, sizeof(lsi)); + } + td->td_retval[0] = 0; + + return (error); +} + +int linux_mknod(struct thread *td, struct linux_mknod_args *args) { char *path; diff --git a/sys/compat/linux/linux_misc.h b/sys/compat/linux/linux_misc.h index be2da81..71d8f1b 100644 --- a/sys/compat/linux/linux_misc.h +++ b/sys/compat/linux/linux_misc.h @@ -125,6 +125,12 @@ extern int stclohz; #define __WALL 0x40000000 #define __WCLONE 0x80000000 +/* Linux waitid idtype */ +#define LINUX_P_ALL 0 +#define LINUX_P_PID 1 +#define LINUX_P_PGID 2 + + int linux_common_wait(struct thread *td, int pid, int *status, int options, struct rusage *ru); void linux_to_bsd_waitopts(int options, int *bsdopts); diff --git a/sys/i386/linux/linux_dummy.c b/sys/i386/linux/linux_dummy.c index 85d40f0..1287a8e 100644 --- a/sys/i386/linux/linux_dummy.c +++ b/sys/i386/linux/linux_dummy.c @@ -80,7 +80,6 @@ DUMMY(mbind); DUMMY(get_mempolicy); DUMMY(set_mempolicy); DUMMY(kexec_load); -DUMMY(waitid); /* linux 2.6.11: */ DUMMY(add_key); DUMMY(request_key); diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master index 09e4f3a..99160c6 100644 --- a/sys/i386/linux/syscalls.master +++ b/sys/i386/linux/syscalls.master @@ -474,7 +474,9 @@ 282 AUE_NULL STD { int linux_mq_getsetattr(l_mqd_t mqd, const struct mq_attr *attr, \ struct mq_attr *oattr); } 283 AUE_NULL STD { int linux_kexec_load(void); } -284 AUE_NULL STD { int linux_waitid(void); } +284 AUE_WAIT6 STD { int linux_waitid(int idtype, l_pid_t id, \ + l_siginfo_t *info, int options, \ + void *rusage); } 285 AUE_NULL UNIMPL ; linux 2.6.11: 286 AUE_NULL STD { int linux_add_key(void); } |