diff options
author | dchagin <dchagin@FreeBSD.org> | 2011-01-28 18:47:07 +0000 |
---|---|---|
committer | dchagin <dchagin@FreeBSD.org> | 2011-01-28 18:47:07 +0000 |
commit | 051ceeb5f3c8cf51e869949c05b1bba132d25804 (patch) | |
tree | 481deadfab18548058f8b5da6648a71e1f2eb473 /sys/amd64/linux32 | |
parent | cc6bdf663542811773e9cfd95af15b63ef575c5f (diff) | |
download | FreeBSD-src-051ceeb5f3c8cf51e869949c05b1bba132d25804.zip FreeBSD-src-051ceeb5f3c8cf51e869949c05b1bba132d25804.tar.gz |
Implement a variation of the linux_common_wait() which should
be used by linuxolator itself.
Move linux_wait4() to MD path as it requires native struct
rusage translation to struct l_rusage on linux32/amd64.
MFC after: 1 Month.
Diffstat (limited to 'sys/amd64/linux32')
-rw-r--r-- | sys/amd64/linux32/linux32_machdep.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c index 68d4e8d..80398ec 100644 --- a/sys/amd64/linux32/linux32_machdep.c +++ b/sys/amd64/linux32/linux32_machdep.c @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include <sys/syscallsubr.h> #include <sys/sysproto.h> #include <sys/unistd.h> +#include <sys/wait.h> #include <machine/frame.h> #include <machine/pcb.h> @@ -66,6 +67,7 @@ __FBSDID("$FreeBSD$"); #include <amd64/linux32/linux.h> #include <amd64/linux32/linux32_proto.h> #include <compat/linux/linux_ipc.h> +#include <compat/linux/linux_misc.h> #include <compat/linux/linux_signal.h> #include <compat/linux/linux_util.h> #include <compat/linux/linux_emul.h> @@ -1272,3 +1274,44 @@ linux_set_thread_area(struct thread *td, return (0); } + +int +linux_wait4(struct thread *td, struct linux_wait4_args *args) +{ + int error, options; + struct rusage ru, *rup; + struct l_rusage lru; + struct proc *p; + +#ifdef DEBUG + if (ldebug(wait4)) + printf(ARGS(wait4, "%d, %p, %d, %p"), + args->pid, (void *)args->status, args->options, + (void *)args->rusage); +#endif + + options = (args->options & (WNOHANG | WUNTRACED)); + /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ + if (args->options & __WCLONE) + options |= WLINUXCLONE; + + if (args->rusage != NULL) + rup = &ru; + else + rup = NULL; + error = linux_common_wait(td, args->pid, args->status, options, rup); + if (error) + return (error); + + p = td->td_proc; + PROC_LOCK(p); + sigqueue_delete(&p->p_sigqueue, SIGCHLD); + PROC_UNLOCK(p); + + if (args->rusage != NULL) { + bsd_to_linux_rusage(rup, &lru); + error = copyout(&lru, args->rusage, sizeof(lru)); + } + + return (error); +} |