diff options
| author | John Baldwin <jhb@FreeBSD.org> | 2004-03-17 20:00:00 +0000 |
|---|---|---|
| committer | John Baldwin <jhb@FreeBSD.org> | 2004-03-17 20:00:00 +0000 |
| commit | b7e23e826c650173f9175c42f1b03cd80fdb0a93 (patch) | |
| tree | e960ffc0a863b368d852fa094d1f4ccb757fe3c7 | |
| parent | cb8c2e1cd289a58a84b0fb4b9703c8847e507a73 (diff) | |
Notes
| -rw-r--r-- | sys/alpha/osf1/osf1_misc.c | 27 | ||||
| -rw-r--r-- | sys/compat/freebsd32/freebsd32_misc.c | 22 | ||||
| -rw-r--r-- | sys/compat/linux/linux_misc.c | 47 | ||||
| -rw-r--r-- | sys/compat/svr4/svr4_misc.c | 32 | ||||
| -rw-r--r-- | sys/i386/ibcs2/ibcs2_misc.c | 38 | ||||
| -rw-r--r-- | sys/kern/kern_exit.c | 123 | ||||
| -rw-r--r-- | sys/sys/wait.h | 6 |
7 files changed, 105 insertions, 190 deletions
diff --git a/sys/alpha/osf1/osf1_misc.c b/sys/alpha/osf1/osf1_misc.c index 8e2557d17c43..373fcc1fe133 100644 --- a/sys/alpha/osf1/osf1_misc.c +++ b/sys/alpha/osf1/osf1_misc.c @@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$"); #include <sys/user.h> #include <sys/utsname.h> #include <sys/vnode.h> +#include <sys/wait.h> #include <vm/vm.h> #include <vm/vm_kern.h> @@ -1376,27 +1377,23 @@ osf1_wait4(td, uap) struct thread *td; struct osf1_wait4_args *uap; { - int error; - caddr_t sg; - struct osf1_rusage *orusage, oru; - struct rusage *rusage = NULL, ru; + int error, status; + struct osf1_rusage oru; + struct rusage ru; - orusage = uap->rusage; - if (orusage) { - sg = stackgap_init(); - rusage = stackgap_alloc(&sg, sizeof(struct rusage)); - uap->rusage = (struct osf1_rusage *)rusage; - } - if ((error = wait4(td, (struct wait_args *)uap))) - return error; - if (orusage && (error = copyin(rusage, &ru, sizeof(ru)) == 0)){ + error = kern_wait(td, uap->pid, &status, uap->options, &ru); + if (error) + return (error); + if (uap->status != NULL) + error = copyout(&status, uap->status, sizeof(status)); + if (uap->rusage != NULL && error == 0) { TV_CP(ru.ru_utime, oru.ru_utime); TV_CP(ru.ru_stime, oru.ru_stime); bcopy(&ru.ru_first, &oru.ru_first, (&(oru.ru_last) - &(oru.ru_first))); - copyout(&oru, orusage, sizeof (struct osf1_rusage)); + error = copyout(&oru, uap->rusage, sizeof (struct osf1_rusage)); } - return (0); + return (error); } diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 511321d9a4fb..deccaf8fc710 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$"); #include <sys/user.h> #include <sys/utsname.h> #include <sys/vnode.h> +#include <sys/wait.h> #include <vm/vm.h> #include <vm/vm_kern.h> @@ -88,21 +89,16 @@ CTASSERT(sizeof(struct rusage32) == 72); int freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) { - int error; - caddr_t sg; - struct rusage32 *rusage32, ru32; - struct rusage *rusage = NULL, ru; + int error, status; + struct rusage32 ru32; + struct rusage ru; - rusage32 = uap->rusage; - if (rusage32) { - sg = stackgap_init(); - rusage = stackgap_alloc(&sg, sizeof(struct rusage)); - uap->rusage = (struct rusage32 *)rusage; - } - error = wait4(td, (struct wait_args *)uap); + error = kern_wait(td, uap->pid, &status, uap->options, &ru); if (error) return (error); - if (rusage32 && (error = copyin(rusage, &ru, sizeof(ru)) == 0)) { + if (uap->status != NULL) + error = copyout(&status, uap->status, sizeof(status)); + if (uap->rusage != NULL && error == 0) { TV_CP(ru, ru32, ru_utime); TV_CP(ru, ru32, ru_stime); CP(ru, ru32, ru_maxrss); @@ -119,7 +115,7 @@ freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) CP(ru, ru32, ru_nsignals); CP(ru, ru32, ru_nvcsw); CP(ru, ru32, ru_nivcsw); - error = copyout(&ru32, rusage32, sizeof(ru32)); + error = copyout(&ru32, uap->rusage, sizeof(ru32)); } return (error); } diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 9e38f91f1f94..8a81dec689ed 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -795,13 +795,7 @@ linux_utime(struct thread *td, struct linux_utime_args *args) int linux_waitpid(struct thread *td, struct linux_waitpid_args *args) { - struct wait_args /* { - int pid; - int *status; - int options; - struct rusage *rusage; - } */ tmp; - int error, tmpstat; + int error, options, tmpstat; #ifdef DEBUG if (ldebug(waitpid)) @@ -809,20 +803,16 @@ linux_waitpid(struct thread *td, struct linux_waitpid_args *args) args->pid, (void *)args->status, args->options); #endif - tmp.pid = args->pid; - tmp.status = args->status; - tmp.options = (args->options & (WNOHANG | WUNTRACED)); + options = (args->options & (WNOHANG | WUNTRACED)); /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ if (args->options & __WCLONE) - tmp.options |= WLINUXCLONE; - tmp.rusage = NULL; + options |= WLINUXCLONE; - if ((error = wait4(td, &tmp)) != 0) + error = kern_wait(td, args->pid, &tmpstat, options, NULL); + if (error) return error; if (args->status) { - if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0) - return error; tmpstat &= 0xffff; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | @@ -840,13 +830,8 @@ linux_waitpid(struct thread *td, struct linux_waitpid_args *args) int linux_wait4(struct thread *td, struct linux_wait4_args *args) { - struct wait_args /* { - int pid; - int *status; - int options; - struct rusage *rusage; - } */ tmp; - int error, tmpstat; + int error, options, tmpstat; + struct rusage ru; struct proc *p; #ifdef DEBUG @@ -856,15 +841,13 @@ linux_wait4(struct thread *td, struct linux_wait4_args *args) (void *)args->rusage); #endif - tmp.pid = args->pid; - tmp.status = args->status; - tmp.options = (args->options & (WNOHANG | WUNTRACED)); + options = (args->options & (WNOHANG | WUNTRACED)); /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ if (args->options & __WCLONE) - tmp.options |= WLINUXCLONE; - tmp.rusage = (struct rusage *)args->rusage; + options |= WLINUXCLONE; - if ((error = wait4(td, &tmp)) != 0) + error = kern_wait(td, args->pid, &tmpstat, options, &ru); + if (error) return error; p = td->td_proc; @@ -873,8 +856,6 @@ linux_wait4(struct thread *td, struct linux_wait4_args *args) PROC_UNLOCK(p); if (args->status) { - if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0) - return error; tmpstat &= 0xffff; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | @@ -882,10 +863,12 @@ linux_wait4(struct thread *td, struct linux_wait4_args *args) else if (WIFSTOPPED(tmpstat)) tmpstat = (tmpstat & 0xffff00ff) | (BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8); - return copyout(&tmpstat, args->status, sizeof(int)); + error = copyout(&tmpstat, args->status, sizeof(int)); } + if (args->rusage != NULL && error == 0) + error = copyout(&ru, args->rusage, sizeof(ru)); - return 0; + return (error); } int diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c index c568a5dc16f2..243dc226aa30 100644 --- a/sys/compat/svr4/svr4_misc.c +++ b/sys/compat/svr4/svr4_misc.c @@ -130,29 +130,12 @@ svr4_sys_wait(td, uap) struct thread *td; struct svr4_sys_wait_args *uap; { - struct wait_args w4; - int error, *retval = td->td_retval, st, sig; - size_t sz = sizeof(*w4.status); + int error, st, sig; - w4.rusage = NULL; - w4.options = 0; - - if (uap->status == NULL) { - caddr_t sg = stackgap_init(); - - w4.status = stackgap_alloc(&sg, sz); - } - else - w4.status = uap->status; - - w4.pid = WAIT_ANY; - - if ((error = wait4(td, &w4)) != 0) - return error; + error = kern_wait(td, WAIT_ANY, &st, 0, NULL); + if (error) + return (error); - if ((error = copyin(w4.status, &st, sizeof(st))) != 0) - return error; - if (WIFSIGNALED(st)) { sig = WTERMSIG(st); if (sig >= 0 && sig < NSIG) @@ -167,13 +150,12 @@ svr4_sys_wait(td, uap) * It looks like wait(2) on svr4/solaris/2.4 returns * the status in retval[1], and the pid on retval[0]. */ - retval[1] = st; + td->td_retval[1] = st; if (uap->status) - if ((error = copyout(&st, uap->status, sizeof(st))) != 0) - return error; + error = copyout(&st, uap->status, sizeof(st)); - return 0; + return (error); } int diff --git a/sys/i386/ibcs2/ibcs2_misc.c b/sys/i386/ibcs2/ibcs2_misc.c index d4162ea6dbde..c3edf1569e2c 100644 --- a/sys/i386/ibcs2/ibcs2_misc.c +++ b/sys/i386/ibcs2/ibcs2_misc.c @@ -144,36 +144,29 @@ ibcs2_wait(td, uap) struct thread *td; struct ibcs2_wait_args *uap; { - int error, status; - struct wait_args w4; + int error, options, status; + int *statusp; + pid_t pid; struct trapframe *tf = td->td_frame; - w4.rusage = NULL; - if ((tf->tf_eflags & (PSL_Z|PSL_PF|PSL_N|PSL_V)) + if ((tf->tf_eflags & (PSL_Z|PSL_PF|PSL_N|PSL_V)) == (PSL_Z|PSL_PF|PSL_N|PSL_V)) { /* waitpid */ - w4.pid = uap->a1; - w4.status = (int *)uap->a2; - w4.options = uap->a3; + pid = uap->a1; + statusp = (int *)uap->a2; + options = uap->a3; } else { /* wait */ - w4.pid = WAIT_ANY; - w4.status = (int *)uap->a1; - w4.options = 0; + pid = WAIT_ANY; + statusp = (int *)uap->a1; + options = 0; } - if ((error = wait4(td, &w4)) != 0) + error = kern_wait(td, pid, &status, options, NULL); + if (error) return error; - if (w4.status) { /* this is real iBCS brain-damage */ - error = copyin((caddr_t)w4.status, (caddr_t)&status, - sizeof(w4.status)); - if(error) - return error; - + if (statusp) { /* - * Convert status/signal result. We must validate the - * signal number stored in the exit status in case - * the user changed it between wait4()'s copyout() - * and our copyin(). + * Convert status/signal result. */ if (WIFSTOPPED(status)) { if (WSTOPSIG(status) <= 0 || @@ -191,8 +184,7 @@ ibcs2_wait(td, uap) /* record result/status */ td->td_retval[1] = status; - return copyout((caddr_t)&status, (caddr_t)w4.status, - sizeof(w4.status)); + return copyout(&status, statusp, sizeof(status)); } return 0; diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index dec3a976fb9d..5f37ca63c7c7 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -85,8 +85,6 @@ __FBSDID("$FreeBSD$"); /* Required to be non-static for SysVR4 emulator */ MALLOC_DEFINE(M_ZOMBIE, "zombie", "zombie proc status"); -static int wait1(struct thread *, struct wait_args *, int); - /* * exit -- * Death of process. @@ -551,57 +549,59 @@ exit1(struct thread *td, int rv) #ifdef COMPAT_43 /* - * MPSAFE. The dirty work is handled by wait1(). + * MPSAFE. The dirty work is handled by kern_wait(). */ int owait(struct thread *td, struct owait_args *uap __unused) { - struct wait_args w; + int error, status; - w.options = 0; - w.rusage = NULL; - w.pid = WAIT_ANY; - w.status = NULL; - return (wait1(td, &w, 1)); + error = kern_wait(td, WAIT_ANY, &status, 0, NULL); + if (error == 0) + td->td_retval[1] = status; + return (error); } #endif /* COMPAT_43 */ /* - * MPSAFE. The dirty work is handled by wait1(). + * MPSAFE. The dirty work is handled by kern_wait(). */ int wait4(struct thread *td, struct wait_args *uap) { - - return (wait1(td, uap, 0)); + struct rusage ru; + int error, status; + + error = kern_wait(td, uap->pid, &status, uap->options, &ru); + if (uap->status != NULL && error == 0) + error = copyout(&status, uap->status, sizeof(status)); + if (uap->rusage != NULL && error == 0) + error = copyout(&ru, uap->rusage, sizeof(struct rusage)); + return (error); } -/* - * MPSAFE - */ -static int -wait1(struct thread *td, struct wait_args *uap, int compat) +int +kern_wait(struct thread *td, pid_t pid, int *status, int options, struct rusage *rusage) { - struct rusage ru; int nfound; struct proc *p, *q, *t; - int status, error; + int error; q = td->td_proc; - if (uap->pid == 0) { + if (pid == 0) { PROC_LOCK(q); - uap->pid = -q->p_pgid; + pid = -q->p_pgid; PROC_UNLOCK(q); } - if (uap->options &~ (WUNTRACED|WNOHANG|WCONTINUED|WLINUXCLONE)) + if (options &~ (WUNTRACED|WNOHANG|WCONTINUED|WLINUXCLONE)) return (EINVAL); loop: nfound = 0; sx_xlock(&proctree_lock); LIST_FOREACH(p, &q->p_children, p_sibling) { PROC_LOCK(p); - if (uap->pid != WAIT_ANY && - p->p_pid != uap->pid && p->p_pgid != -uap->pid) { + if (pid != WAIT_ANY && + p->p_pid != pid && p->p_pgid != -pid) { PROC_UNLOCK(p); continue; } @@ -615,7 +615,7 @@ loop: * signifies we want to wait for threads and not processes. */ if ((p->p_sigparent != SIGCHLD) ^ - ((uap->options & WLINUXCLONE) != 0)) { + ((options & WLINUXCLONE) != 0)) { PROC_UNLOCK(p); continue; } @@ -623,37 +623,16 @@ loop: nfound++; if (p->p_state == PRS_ZOMBIE) { td->td_retval[0] = p->p_pid; -#ifdef COMPAT_43 - if (compat) - td->td_retval[1] = p->p_xstat; - else -#endif - if (uap->status) { - status = p->p_xstat; /* convert to int */ - PROC_UNLOCK(p); - if ((error = copyout(&status, - uap->status, sizeof(status)))) { - sx_xunlock(&proctree_lock); - mtx_unlock(&Giant); - return (error); - } - PROC_LOCK(p); - } - if (uap->rusage) { - bcopy(p->p_ru, &ru, sizeof(ru)); - PROC_UNLOCK(p); - if ((error = copyout(&ru, - uap->rusage, sizeof (struct rusage)))) { - sx_xunlock(&proctree_lock); - mtx_unlock(&Giant); - return (error); - } - } else - PROC_UNLOCK(p); + if (status) + *status = p->p_xstat; /* convert to int */ + if (rusage) + bcopy(p->p_ru, rusage, sizeof(struct rusage)); + /* * If we got the child via a ptrace 'attach', * we need to give it back to the old parent. */ + PROC_UNLOCK(p); if (p->p_oppid && (t = pfind(p->p_oppid)) != NULL) { PROC_LOCK(p); p->p_oppid = 0; @@ -725,7 +704,7 @@ loop: mac_destroy_proc(p); #endif KASSERT(FIRST_THREAD_IN_PROC(p), - ("wait1: no residual thread!")); + ("kern_wait: no residual thread!")); uma_zfree(proc_zone, p); sx_xlock(&allproc_lock); nprocs--; @@ -735,44 +714,26 @@ loop: mtx_lock_spin(&sched_lock); if (P_SHOULDSTOP(p) && (p->p_suspcount == p->p_numthreads) && ((p->p_flag & P_WAITED) == 0) && - (p->p_flag & P_TRACED || uap->options & WUNTRACED)) { + (p->p_flag & P_TRACED || options & WUNTRACED)) { mtx_unlock_spin(&sched_lock); p->p_flag |= P_WAITED; sx_xunlock(&proctree_lock); td->td_retval[0] = p->p_pid; -#ifdef COMPAT_43 - if (compat) { - td->td_retval[1] = W_STOPCODE(p->p_xstat); - PROC_UNLOCK(p); - error = 0; - } else -#endif - if (uap->status) { - status = W_STOPCODE(p->p_xstat); - PROC_UNLOCK(p); - error = copyout(&status, - uap->status, sizeof(status)); - } else { - PROC_UNLOCK(p); - error = 0; - } - return (error); + if (status) + *status = W_STOPCODE(p->p_xstat); + PROC_UNLOCK(p); + return (0); } mtx_unlock_spin(&sched_lock); - if (uap->options & WCONTINUED && (p->p_flag & P_CONTINUED)) { + if (options & WCONTINUED && (p->p_flag & P_CONTINUED)) { sx_xunlock(&proctree_lock); td->td_retval[0] = p->p_pid; p->p_flag &= ~P_CONTINUED; PROC_UNLOCK(p); - if (uap->status) { - status = SIGCONT; - error = copyout(&status, - uap->status, sizeof(status)); - } else - error = 0; - - return (error); + if (status) + *status = SIGCONT; + return (0); } PROC_UNLOCK(p); } @@ -780,7 +741,7 @@ loop: sx_xunlock(&proctree_lock); return (ECHILD); } - if (uap->options & WNOHANG) { + if (options & WNOHANG) { sx_xunlock(&proctree_lock); td->td_retval[0] = 0; return (0); diff --git a/sys/sys/wait.h b/sys/sys/wait.h index 74ed683068fe..965c470a40ea 100644 --- a/sys/sys/wait.h +++ b/sys/sys/wait.h @@ -96,7 +96,11 @@ #define WAIT_MYPGRP 0 /* any process in my process group */ #endif /* __BSD_VISIBLE */ -#ifndef _KERNEL +#ifdef _KERNEL +int kern_wait(struct thread *td, pid_t pid, int *status, int options, + struct rusage *rusage); + +#else #include <sys/types.h> __BEGIN_DECLS |
