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:
parent
5512f35a12
commit
5d97669cfe
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 *));
|
||||
|
@ -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: */
|
||||
|
Loading…
Reference in New Issue
Block a user