From 906bfde06de3d3488c43cb98165aefb174df6290 Mon Sep 17 00:00:00 2001 From: joerg Date: Sat, 13 Sep 1997 19:42:29 +0000 Subject: [PATCH] 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 --- sys/kern/kern_exit.c | 18 ++++++++++++++++-- sys/kern/kern_sig.c | 17 ++++++++++++++++- sys/sys/_sigset.h | 3 ++- sys/sys/proc.h | 5 ++++- sys/sys/signal.h | 3 ++- 5 files changed, 40 insertions(+), 6 deletions(-) diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 7d326da9fd9b..1fb9077797de 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.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) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index b73503e3111d..fb78d3e1ff67 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -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, diff --git a/sys/sys/_sigset.h b/sys/sys/_sigset.h index f461a99d55c2..ee3cabb4cae4 100644 --- a/sys/sys/_sigset.h +++ b/sys/sys/_sigset.h @@ -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 diff --git a/sys/sys/proc.h b/sys/sys/proc.h index cb64b36daa72..842a541726af 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -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? * diff --git a/sys/sys/signal.h b/sys/sys/signal.h index f461a99d55c2..ee3cabb4cae4 100644 --- a/sys/sys/signal.h +++ b/sys/sys/signal.h @@ -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