Allow an alternate exit signal (i.e. not SIGCHLD) to be delivered to the

parent, specified at fork time.  Specify a new flag to wait4(2), WALTSIG,
to wait for processes which use an alternate exit signal.

This is required for clone(2).
This commit is contained in:
thorpej 1999-05-13 00:59:03 +00:00
parent 5512f35a12
commit 5d97669cfe
6 changed files with 48 additions and 21 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: init_main.c,v 1.149 1999/04/30 21:23:49 thorpej Exp $ */
/* $NetBSD: init_main.c,v 1.150 1999/05/13 00:59:04 thorpej Exp $ */
/*
* Copyright (c) 1995 Christopher G. Demetriou. All rights reserved.
@ -404,7 +404,7 @@ main()
siginit(p);
/* Create process 1 (init(8)). */
if (fork1(p, 0, NULL, &initproc))
if (fork1(p, 0, SIGCHLD, NULL, &initproc))
panic("fork init");
cpu_set_kpc(initproc, start_init, initproc);

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_exit.c,v 1.67 1999/04/30 21:23:49 thorpej Exp $ */
/* $NetBSD: kern_exit.c,v 1.68 1999/05/13 00:59:04 thorpej Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -376,9 +376,9 @@ reaper()
/* Process is now a true zombie. */
LIST_INSERT_HEAD(&zombproc, p, p_list);
/* Wake up the parent so it can get exit satus. */
/* Wake up the parent so it can get exit status. */
if ((p->p_flag & P_FSTRACE) == 0)
psignal(p->p_pptr, SIGCHLD);
psignal(p->p_pptr, P_EXITSIG(p));
wakeup((caddr_t)p->p_pptr);
}
}
@ -401,7 +401,7 @@ sys_wait4(q, v, retval)
if (SCARG(uap, pid) == 0)
SCARG(uap, pid) = -q->p_pgid;
if (SCARG(uap, options) &~ (WUNTRACED|WNOHANG))
if (SCARG(uap, options) &~ (WUNTRACED|WNOHANG|WALTSIG))
return (EINVAL);
loop:
@ -411,6 +411,15 @@ loop:
p->p_pid != SCARG(uap, pid) &&
p->p_pgid != -SCARG(uap, pid))
continue;
/*
* Wait for processes with p_exitsig != SIGCHLD processes only
* if WALTSIG is set; wait for processes with p_exitsig ==
* SIGCHLD only if WALTSIG is clear.
*/
if ((SCARG(uap, options) & WALTSIG) ? p->p_exitsig == SIGCHLD :
p->p_exitsig != SIGCHLD)
continue;
nfound++;
if (p->p_stat == SZOMB) {
retval[0] = p->p_pid;
@ -433,8 +442,8 @@ loop:
* the parent is different (meaning the process was
* attached, rather than run as a child), then we need
* to give it back to the old parent, and send the
* parent a SIGCHLD. The rest of the cleanup will be
* done when the old parent waits on the child.
* parent the exit signal. The rest of the cleanup
* will be done when the old parent waits on the child.
*/
if ((p->p_flag & P_TRACED) &&
p->p_oppid != p->p_pptr->p_pid) {
@ -442,7 +451,7 @@ loop:
proc_reparent(p, t ? t : initproc);
p->p_oppid = 0;
p->p_flag &= ~(P_TRACED|P_WAITED|P_FSTRACE);
psignal(p->p_pptr, SIGCHLD);
psignal(p->p_pptr, P_EXITSIG(p));
wakeup((caddr_t)p->p_pptr);
return (0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_fork.c,v 1.57 1999/04/30 21:39:51 thorpej Exp $ */
/* $NetBSD: kern_fork.c,v 1.58 1999/05/13 00:59:04 thorpej Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1993
@ -77,7 +77,7 @@ sys_fork(p, v, retval)
register_t *retval;
{
return (fork1(p, 0, retval, NULL));
return (fork1(p, 0, SIGCHLD, retval, NULL));
}
/*
@ -92,7 +92,7 @@ sys_vfork(p, v, retval)
register_t *retval;
{
return (fork1(p, FORK_PPWAIT, retval, NULL));
return (fork1(p, FORK_PPWAIT, SIGCHLD, retval, NULL));
}
/*
@ -107,13 +107,14 @@ sys___vfork14(p, v, retval)
register_t *retval;
{
return (fork1(p, FORK_PPWAIT|FORK_SHAREVM, retval, NULL));
return (fork1(p, FORK_PPWAIT|FORK_SHAREVM, SIGCHLD, retval, NULL));
}
int
fork1(p1, flags, retval, rnewprocp)
fork1(p1, flags, exitsig, retval, rnewprocp)
register struct proc *p1;
int flags;
int exitsig;
register_t *retval;
struct proc **rnewprocp;
{
@ -233,6 +234,9 @@ again:
/* Record the pid we've allocated. */
p2->p_pid = nextpid;
/* Record the signal to be delivered to the parent on exit. */
p2->p_exitsig = exitsig;
/*
* Put the proc on allproc before unlocking PID allocation
* so that waiters won't grab it as soon as we unlock.

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_kthread.c,v 1.5 1999/04/30 21:40:30 thorpej Exp $ */
/* $NetBSD: kern_kthread.c,v 1.6 1999/05/13 00:59:04 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@ -76,7 +76,7 @@ kthread_create(func, arg, newpp, fmt, va_alist)
/* First, create the new process. */
error = fork1(&proc0, FORK_SHAREVM | FORK_SHARECWD | FORK_SHAREFILES |
FORK_SHARESIGS, NULL, &p2);
FORK_SHARESIGS, SIGCHLD, NULL, &p2);
if (error)
return (error);

View File

@ -1,4 +1,4 @@
/* $NetBSD: proc.h,v 1.75 1999/04/30 18:40:05 thorpej Exp $ */
/* $NetBSD: proc.h,v 1.76 1999/05/13 00:59:03 thorpej Exp $ */
/*-
* Copyright (c) 1986, 1989, 1991, 1993
@ -123,6 +123,7 @@ struct proc {
#define p_ucred p_cred->pc_ucred
#define p_rlimit p_limit->pl_rlimit
int p_exitsig; /* signal to sent to parent on exit */
int p_flag; /* P_* flags. */
u_char p_unused; /* XXX: used to be emulation flag */
char p_stat; /* S* process status. */
@ -230,6 +231,13 @@ struct proc {
#define P_FSTRACE 0x10000 /* Debugger process being traced by procfs */
#define P_NOCLDWAIT 0x20000 /* No zombies if child dies */
/*
* Macro to compute the exit signal.
*/
#define P_EXITSIG(p) ((((p)->p_flag & (P_TRACED|P_FSTRACE)) || \
(p)->p_pptr == initproc) ? \
SIGCHLD : p->p_exitsig)
/*
* MOVE TO ucred.h?
*
@ -349,7 +357,7 @@ void wakeup __P((void *chan));
void reaper __P((void));
void exit1 __P((struct proc *, int));
void exit2 __P((struct proc *));
int fork1 __P((struct proc *, int, register_t *, struct proc **));
int fork1 __P((struct proc *, int, int, register_t *, struct proc **));
void kmeminit __P((void));
void rqinit __P((void));
int groupmember __P((gid_t, struct ucred *));

View File

@ -1,4 +1,4 @@
/* $NetBSD: wait.h,v 1.14 1998/12/16 10:08:35 christos Exp $ */
/* $NetBSD: wait.h,v 1.15 1999/05/13 00:59:03 thorpej Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993, 1994
@ -78,8 +78,14 @@
* this option is done, it is as though they were still running... nothing
* about them is returned.
*/
#define WNOHANG 1 /* don't hang in wait */
#define WUNTRACED 2 /* tell about stopped, untraced children */
#define WNOHANG 0x00000001 /* don't hang in wait */
#define WUNTRACED 0x00000002 /* tell about stopped,
untraced children */
#ifndef _POSIX_SOURCE
#define WALTSIG 0x00000004 /* wait for processes that exit
with an alternate signal (i.e.
not SIGCHLD) */
#endif
#ifndef _POSIX_SOURCE
/* POSIX extensions and 4.2/4.3 compatability: */