changeset 10043:397682150a87

6857047 sigwait malfunctions for system-generated SIGCHLD signals
author Roger A. Faulkner <Roger.Faulkner@Sun.COM>
date Mon, 06 Jul 2009 17:16:19 -0700
parents c022bae2f0d3
children 2643c1cd9e2a
files usr/src/uts/common/os/sig.c usr/src/uts/common/syscall/sigaction.c usr/src/uts/common/syscall/ssig.c
diffstat 3 files changed, 19 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/os/sig.c	Mon Jul 06 17:03:56 2009 -0700
+++ b/usr/src/uts/common/os/sig.c	Mon Jul 06 17:16:19 2009 -0700
@@ -481,7 +481,7 @@
 				 * the process when lwp_nostop is set.
 				 */
 				if (!lwp->lwp_nostop ||
-				    PTOU(curproc)->u_signal[sig-1] != SIG_DFL ||
+				    PTOU(p)->u_signal[sig-1] != SIG_DFL ||
 				    !sigismember(&stopdefault, sig))
 					return (1);
 			}
@@ -683,8 +683,6 @@
 		 */
 		for (;;) {
 			if ((sig = fsig(&t->t_sig, t)) != 0) {
-				if (sig == SIGCLD)
-					sigcld_found = 1;
 				toproc = 0;
 				if (tracing(p, sig) ||
 				    sigismember(&t->t_sigwait, sig) ||
@@ -766,15 +764,10 @@
 	mutex_exit(&p->p_lock);
 
 	/*
-	 * If SIGCLD was dequeued, search for other pending SIGCLD's.
-	 * Don't do it if we are returning SIGCLD and the signal
-	 * handler will be reset by psig(); this enables reliable
-	 * delivery of SIGCLD even when using the old, broken
-	 * signal() interface for setting the signal handler.
+	 * If SIGCLD was dequeued from the process's signal queue,
+	 * search for other pending SIGCLD's from the list of children.
 	 */
-	if (sigcld_found &&
-	    (sig != SIGCLD || !sigismember(&PTOU(curproc)->u_sigresethand,
-	    SIGCLD)))
+	if (sigcld_found)
 		sigcld_repost();
 
 	if (sig != 0)
@@ -1586,7 +1579,6 @@
 			sigaddset(&PTOU(curproc)->u_sigonstack, sig);
 		else
 			sigdelset(&PTOU(curproc)->u_sigonstack, sig);
-
 	} else if (disp == SIG_IGN ||
 	    (disp == SIG_DFL && sigismember(&ignoredefault, sig))) {
 		/*
@@ -1605,7 +1597,6 @@
 			sigdelset(&t->t_extsig, sig);
 			sigdelq(p, t, sig);
 		} while ((t = t->t_forw) != p->p_tlist);
-
 	} else {
 		/*
 		 * The signal action is being set to SIG_DFL and the default
@@ -1729,7 +1720,8 @@
 }
 
 /*
- * Common code called from sigcld() and issig_forreal()
+ * Common code called from sigcld() and from
+ * waitid() and issig_forreal() via sigcld_repost().
  * Give the parent process a SIGCLD if it does not have one pending,
  * else mark the child process so a SIGCLD can be posted later.
  */
@@ -1737,22 +1729,20 @@
 post_sigcld(proc_t *cp, sigqueue_t *sqp)
 {
 	proc_t *pp = cp->p_parent;
-	void (*handler)() = PTOU(pp)->u_signal[SIGCLD - 1];
 	k_siginfo_t info;
 
 	ASSERT(MUTEX_HELD(&pidlock));
 	mutex_enter(&pp->p_lock);
 
 	/*
-	 * If a SIGCLD is pending, or if SIGCLD is not now being caught,
-	 * then just mark the child process so that its SIGCLD will
-	 * be posted later, when the first SIGCLD is taken off the
-	 * queue or when the parent is ready to receive it, if ever.
+	 * If a SIGCLD is pending, then just mark the child process
+	 * so that its SIGCLD will be posted later, when the first
+	 * SIGCLD is taken off the queue or when the parent is ready
+	 * to receive it or accept it, if ever.
 	 */
-	if (handler == SIG_DFL || handler == SIG_IGN ||
-	    sigismember(&pp->p_sig, SIGCLD))
+	if (sigismember(&pp->p_sig, SIGCLD)) {
 		cp->p_pidflag |= CLDPEND;
-	else {
+	} else {
 		cp->p_pidflag &= ~CLDPEND;
 		if (sqp == NULL) {
 			/*
@@ -1787,15 +1777,8 @@
 {
 	proc_t *pp = curproc;
 	proc_t *cp;
-	void (*handler)() = PTOU(pp)->u_signal[SIGCLD - 1];
 	sigqueue_t *sqp;
 
-	/*
-	 * Don't bother if SIGCLD is not now being caught.
-	 */
-	if (handler == SIG_DFL || handler == SIG_IGN)
-		return;
-
 	sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP);
 	mutex_enter(&pidlock);
 	for (cp = pp->p_child; cp; cp = cp->p_sibling) {
--- a/usr/src/uts/common/syscall/sigaction.c	Mon Jul 06 17:03:56 2009 -0700
+++ b/usr/src/uts/common/syscall/sigaction.c	Mon Jul 06 17:16:19 2009 -0700
@@ -20,16 +20,13 @@
  */
 
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
 /*	  All Rights Reserved	*/
 
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/sysmacros.h>
@@ -115,11 +112,8 @@
 	}
 
 	if (actp) {
-		if (sig == SIGCLD &&
-		    act.sa_handler != SIG_IGN &&
-		    act.sa_handler != SIG_DFL)
+		if (sig == SIGCLD)
 			sigcld_look = 1;
-
 		sigutok(&act.sa_mask, &set);
 		setsigact(sig, act.sa_handler, set, act.sa_flags);
 	}
@@ -211,11 +205,8 @@
 	}
 
 	if (actp) {
-		if (sig == SIGCLD &&
-		    act32.sa_handler != (caddr32_t)SIG_IGN &&
-		    act32.sa_handler != (caddr32_t)SIG_DFL)
+		if (sig == SIGCLD)
 			sigcld_look = 1;
-
 		sigutok(&act32.sa_mask, &set);
 		setsigact(sig, (void (*)())(uintptr_t)act32.sa_handler, set,
 		    act32.sa_flags);
--- a/usr/src/uts/common/syscall/ssig.c	Mon Jul 06 17:03:56 2009 -0700
+++ b/usr/src/uts/common/syscall/ssig.c	Mon Jul 06 17:16:19 2009 -0700
@@ -18,16 +18,14 @@
  *
  * CDDL HEADER END
  */
-/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
-/*	  All Rights Reserved	*/
-
 
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
+/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
+/*	  All Rights Reserved	*/
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -154,8 +152,7 @@
 		flags |= SA_NOCLDSTOP;
 		if (func == SIG_IGN)
 			flags |= SA_NOCLDWAIT;
-		else if (func != SIG_DFL)
-			sigcld_look = 1;
+		sigcld_look = 1;
 	}
 
 	setsigact(sig, func, nullsmask, flags);