diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index da1293cb86a5..76684546ba99 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_misc.c,v 1.51 1999/01/06 23:05:38 julian Exp $ + * $Id: linux_misc.c,v 1.52 1999/01/26 02:38:10 julian Exp $ */ #include @@ -554,7 +554,7 @@ linux_fork(struct proc *p, struct linux_fork_args *args) #ifdef DEBUG printf("Linux-emul(%d): fork()\n", p->p_pid); #endif - if (error = fork(p, (struct fork_args *)args)) + if ((error = fork(p, (struct fork_args *)args)) != 0) return error; if (p->p_retval[1] == 1) p->p_retval[0] = 0; @@ -589,6 +589,7 @@ linux_clone(struct proc *p, struct linux_clone_args *args) if (!args->stack) return (EINVAL); + exit_signal = args->flags & 0x000000ff; if (exit_signal >= LINUX_NSIG) return EINVAL; @@ -608,7 +609,7 @@ linux_clone(struct proc *p, struct linux_clone_args *args) start = 0; rf_args.flags = ff; - if (error = rfork(p, &rf_args)) + if ((error = rfork(p, &rf_args)) != 0) return error; p2 = pfind(p->p_retval[0]); @@ -936,6 +937,8 @@ linux_utime(struct proc *p, struct linux_utime_args *args) return utimes(p, &bsdutimes); } +#define __WCLONE 0x80000000 + int linux_waitpid(struct proc *p, struct linux_waitpid_args *args) { @@ -953,20 +956,17 @@ linux_waitpid(struct proc *p, struct linux_waitpid_args *args) #endif tmp.pid = args->pid; tmp.status = args->status; - /* This filters out the linux option _WCLONE. I don't - * think we need it, but I could be wrong. If we need - * it, we need to fix wait4, since it will give us an - * error return of EINVAL if we pass in _WCLONE, and - * of course, it won't do anything with it. - */ tmp.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; - if (error = wait4(p, &tmp)) + if ((error = wait4(p, &tmp)) != 0) return error; if (args->status) { - if (error = copyin(args->status, &tmpstat, sizeof(int))) + if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0) return error; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | @@ -997,22 +997,19 @@ linux_wait4(struct proc *p, struct linux_wait4_args *args) #endif tmp.pid = args->pid; tmp.status = args->status; - /* This filters out the linux option _WCLONE. I don't - * think we need it, but I could be wrong. If we need - * it, we need to fix wait4, since it will give us an - * error return of EINVAL if we pass in _WCLONE, and - * of course, it won't do anything with it. - */ tmp.options = (args->options & (WNOHANG | WUNTRACED)); + /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ + if (args->options & __WCLONE) + tmp.options |= WLINUXCLONE; tmp.rusage = args->rusage; - if (error = wait4(p, &tmp)) + if ((error = wait4(p, &tmp)) != 0) return error; p->p_siglist &= ~sigmask(SIGCHLD); if (args->status) { - if (error = copyin(args->status, &tmpstat, sizeof(int))) + if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0) return error; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | diff --git a/sys/i386/linux/linux_misc.c b/sys/i386/linux/linux_misc.c index da1293cb86a5..76684546ba99 100644 --- a/sys/i386/linux/linux_misc.c +++ b/sys/i386/linux/linux_misc.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_misc.c,v 1.51 1999/01/06 23:05:38 julian Exp $ + * $Id: linux_misc.c,v 1.52 1999/01/26 02:38:10 julian Exp $ */ #include @@ -554,7 +554,7 @@ linux_fork(struct proc *p, struct linux_fork_args *args) #ifdef DEBUG printf("Linux-emul(%d): fork()\n", p->p_pid); #endif - if (error = fork(p, (struct fork_args *)args)) + if ((error = fork(p, (struct fork_args *)args)) != 0) return error; if (p->p_retval[1] == 1) p->p_retval[0] = 0; @@ -589,6 +589,7 @@ linux_clone(struct proc *p, struct linux_clone_args *args) if (!args->stack) return (EINVAL); + exit_signal = args->flags & 0x000000ff; if (exit_signal >= LINUX_NSIG) return EINVAL; @@ -608,7 +609,7 @@ linux_clone(struct proc *p, struct linux_clone_args *args) start = 0; rf_args.flags = ff; - if (error = rfork(p, &rf_args)) + if ((error = rfork(p, &rf_args)) != 0) return error; p2 = pfind(p->p_retval[0]); @@ -936,6 +937,8 @@ linux_utime(struct proc *p, struct linux_utime_args *args) return utimes(p, &bsdutimes); } +#define __WCLONE 0x80000000 + int linux_waitpid(struct proc *p, struct linux_waitpid_args *args) { @@ -953,20 +956,17 @@ linux_waitpid(struct proc *p, struct linux_waitpid_args *args) #endif tmp.pid = args->pid; tmp.status = args->status; - /* This filters out the linux option _WCLONE. I don't - * think we need it, but I could be wrong. If we need - * it, we need to fix wait4, since it will give us an - * error return of EINVAL if we pass in _WCLONE, and - * of course, it won't do anything with it. - */ tmp.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; - if (error = wait4(p, &tmp)) + if ((error = wait4(p, &tmp)) != 0) return error; if (args->status) { - if (error = copyin(args->status, &tmpstat, sizeof(int))) + if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0) return error; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | @@ -997,22 +997,19 @@ linux_wait4(struct proc *p, struct linux_wait4_args *args) #endif tmp.pid = args->pid; tmp.status = args->status; - /* This filters out the linux option _WCLONE. I don't - * think we need it, but I could be wrong. If we need - * it, we need to fix wait4, since it will give us an - * error return of EINVAL if we pass in _WCLONE, and - * of course, it won't do anything with it. - */ tmp.options = (args->options & (WNOHANG | WUNTRACED)); + /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ + if (args->options & __WCLONE) + tmp.options |= WLINUXCLONE; tmp.rusage = args->rusage; - if (error = wait4(p, &tmp)) + if ((error = wait4(p, &tmp)) != 0) return error; p->p_siglist &= ~sigmask(SIGCHLD); if (args->status) { - if (error = copyin(args->status, &tmpstat, sizeof(int))) + if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0) return error; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index c80b3c8adb9d..297d9a7260ca 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_exit.c 8.7 (Berkeley) 2/12/94 - * $Id: kern_exit.c,v 1.74 1999/01/31 03:15:13 newton Exp $ + * $Id: kern_exit.c,v 1.75 1999/02/19 14:25:34 luoqi Exp $ */ #include "opt_compat.h" @@ -283,7 +283,7 @@ exit1(p, rv) LIST_REMOVE(q, p_sibling); LIST_INSERT_HEAD(&initproc->p_children, q, p_sibling); q->p_pptr = initproc; - q->p_sigparent = 0; + q->p_sigparent = SIGCHLD; /* * Traced processes are killed * since their existence means someone is screwing up. @@ -420,7 +420,7 @@ wait1(q, uap, compat) if (uap->pid == 0) uap->pid = -q->p_pgid; - if (uap->options &~ (WUNTRACED|WNOHANG)) + if (uap->options &~ (WUNTRACED|WNOHANG|WLINUXCLONE)) return (EINVAL); loop: nfound = 0; @@ -428,6 +428,17 @@ wait1(q, uap, compat) if (uap->pid != WAIT_ANY && p->p_pid != uap->pid && p->p_pgid != -uap->pid) continue; + + /* This special case handles a kthread spawned by linux_clone + * (see linux_misc.c). The linux_wait4 and linux_waitpid functions + * need to be able to distinguish between waiting on a process and + * waiting on a thread. It is a thread if p_sigparent is not SIGCHLD, + * and the WLINUXCLONE option signifies we want to wait for threads + * and not processes. + */ + if ((p->p_sigparent != SIGCHLD) ^ ((uap->options & WLINUXCLONE) != 0)) + continue; + nfound++; if (p->p_stat == SZOMB) { /* charge childs scheduling cpu usage to parent */ diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 1ee86ae241e3..2877636e63d3 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_fork.c 8.6 (Berkeley) 4/8/94 - * $Id: kern_fork.c,v 1.54 1999/01/07 21:23:42 julian Exp $ + * $Id: kern_fork.c,v 1.55 1999/01/26 02:38:10 julian Exp $ */ #include "opt_ktrace.h" @@ -361,9 +361,10 @@ fork1(p1, flags) /* Note that we fill in the values of sigacts in vm_fork */ p2->p_sigacts = NULL; } - if (flags & RFLINUXTHPN) { + if (flags & RFLINUXTHPN) p2->p_sigparent = SIGUSR1; - } + else + p2->p_sigparent = SIGCHLD; /* bump references to the text vnode (for procfs) */ p2->p_textvp = p1->p_textvp; diff --git a/sys/sys/wait.h b/sys/sys/wait.h index 0c8ea1b339fd..b0716d27fa7a 100644 --- a/sys/sys/wait.h +++ b/sys/sys/wait.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)wait.h 8.2 (Berkeley) 7/10/94 - * $Id$ + * $Id: wait.h,v 1.8 1997/02/22 09:46:31 peter Exp $ */ #ifndef _SYS_WAIT_H_ @@ -79,6 +79,7 @@ */ #define WNOHANG 1 /* don't hang in wait */ #define WUNTRACED 2 /* tell about stopped, untraced children */ +#define WLINUXCLONE 0x80000000 /* wait for kthread spawned from linux_clone */ #ifndef _POSIX_SOURCE /* POSIX extensions and 4.2/4.3 compatibility: */