Implement SA_NOCLDWAIT.

The implementation is done (unlike what i've originally been
contemplating) by reparenting kids of processes that have the
appropriate bit set to PID 1, and let PID 1 handle the zombie.  This
is far less problematical than what would seem to be ``doing it
right'', for a number of reasons.

Of our currently shipping PID-1-intended programs, 50 % fail the above
assumption. ;-)  (Read this: sysinstall doesn't do it right.  This is
no problem as long as no program called by sysinstall actually uses
SA_NOCLDWAIT.)

ToDo:		. clarify the correct SA_* flag inheritance, compared
		  to other systems,
		. decide whether the compat cruft (osigvec(9)) should
		  deal with new system additions or not,
		. merge OpenBSD's SA_SIGINFO implementation. ;)
Reviewed by:	bde
This commit is contained in:
Joerg Wunsch 1997-09-13 19:42:29 +00:00
parent 6ae8628b06
commit 245f17d43c
5 changed files with 40 additions and 6 deletions

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
* $Id: kern_exit.c,v 1.53 1997/08/26 00:11:55 bde Exp $
* $Id: kern_exit.c,v 1.54 1997/09/02 20:05:38 bde Exp $
*/
#include "opt_ktrace.h"
@ -294,8 +294,22 @@ exit1(p, rv)
ruadd(p->p_ru, &p->p_stats->p_cru);
/*
* Notify parent that we're gone.
* Notify parent that we're gone. If parent has the P_NOCLDWAIT
* flag set, notify process 1 instead (and hope it will handle
* this situation).
*/
if (p->p_pptr->p_flag & P_NOCLDWAIT) {
struct proc *pp = p->p_pptr;
proc_reparent(p, initproc);
/*
* If this was the last child of our parent, notify
* parent, so in case he was wait(2)ing, he will
* continue.
*/
if (LIST_EMPTY(&pp->p_children))
wakeup((caddr_t)pp);
}
psignal(p->p_pptr, SIGCHLD);
wakeup((caddr_t)p->p_pptr);
#if defined(tahoe)

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_sig.c 8.7 (Berkeley) 4/18/94
* $Id: kern_sig.c,v 1.32 1997/08/26 00:31:04 bde Exp $
* $Id: kern_sig.c,v 1.33 1997/09/02 20:05:41 bde Exp $
*/
#include "opt_ktrace.h"
@ -123,6 +123,8 @@ sigaction(p, uap, retval)
sa->sa_flags |= SA_NODEFER;
if (signum == SIGCHLD && p->p_flag & P_NOCLDSTOP)
sa->sa_flags |= SA_NOCLDSTOP;
if (signum == SIGCHLD && p->p_flag & P_NOCLDWAIT)
sa->sa_flags |= SA_NOCLDWAIT;
if ((error = copyout((caddr_t)sa, (caddr_t)uap->osa,
sizeof (vec))))
return (error);
@ -182,6 +184,19 @@ setsigvec(p, signum, sa)
p->p_flag |= P_NOCLDSTOP;
else
p->p_flag &= ~P_NOCLDSTOP;
if (sa->sa_flags & SA_NOCLDWAIT) {
/*
* Paranoia: since SA_NOCLDWAIT is implemented by
* reparenting the dying child to PID 1 (and
* trust it to reap the zombie), PID 1 itself is
* forbidden to set SA_NOCLDWAIT.
*/
if (p->p_pid == 1)
p->p_flag &= ~P_NOCLDWAIT;
else
p->p_flag |= P_NOCLDWAIT;
} else
p->p_flag &= ~P_NOCLDWAIT;
}
/*
* Set bit in p_sigignore for signals that are set to SIG_IGN,

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)signal.h 8.4 (Berkeley) 5/4/95
* $Id$
* $Id: signal.h,v 1.11 1997/02/22 09:45:53 peter Exp $
*/
#ifndef _SYS_SIGNAL_H_
@ -132,6 +132,7 @@ struct sigaction {
#define SA_RESTART 0x0002 /* restart system call on signal return */
#define SA_RESETHAND 0x0004 /* reset to SIG_DFL when taking signal */
#define SA_NODEFER 0x0010 /* don't mask the signal we're delivering */
#define SA_NOCLDWAIT 0x0020 /* don't keep zombies around */
#ifdef COMPAT_SUNOS
#define SA_USERTRAMP 0x0100 /* do not bounce off kernel's sigtramp */
#endif

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)proc.h 8.15 (Berkeley) 5/19/95
* $Id: proc.h,v 1.41 1997/06/22 16:04:22 peter Exp $
* $Id: proc.h,v 1.42 1997/07/06 02:40:36 dyson Exp $
*/
#ifndef _SYS_PROC_H_
@ -224,6 +224,9 @@ struct proc {
/* Marked a kernel thread */
#define P_KTHREADP 0x200000 /* Process is really a kernel thread */
#define P_NOCLDWAIT 0x400000 /* No zombies if child dies */
/*
* MOVE TO ucred.h?
*

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)signal.h 8.4 (Berkeley) 5/4/95
* $Id$
* $Id: signal.h,v 1.11 1997/02/22 09:45:53 peter Exp $
*/
#ifndef _SYS_SIGNAL_H_
@ -132,6 +132,7 @@ struct sigaction {
#define SA_RESTART 0x0002 /* restart system call on signal return */
#define SA_RESETHAND 0x0004 /* reset to SIG_DFL when taking signal */
#define SA_NODEFER 0x0010 /* don't mask the signal we're delivering */
#define SA_NOCLDWAIT 0x0020 /* don't keep zombies around */
#ifdef COMPAT_SUNOS
#define SA_USERTRAMP 0x0100 /* do not bounce off kernel's sigtramp */
#endif