Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Jan 2011 13:56:41 +0000 (UTC)
From:      Jilles Tjoelker <jilles@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r217472 - in head: bin/sh tools/regression/bin/sh/builtins
Message-ID:  <201101161356.p0GDuf9O065545@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jilles
Date: Sun Jan 16 13:56:41 2011
New Revision: 217472
URL: http://svn.freebsd.org/changeset/base/217472

Log:
  sh: If exit is used without args from a trap action, exit on the signal.
  
  This is useful so that it is easier to exit on a signal than to reset the
  trap to default and resend the signal. It matches ksh93. POSIX says that
  'exit' without args from a trap action uses the exit status from the last
  command before the trap, which is different from 'exit $?' and matches this
  if the previous command is assumed to have exited on the signal.
  
  If the signal is SIGSTOP, SIGTSTP, SIGTTIN or SIGTTOU, or if the default
  action for the signal is to ignore it, a normal _exit(2) is done with exit
  status 128+signal_number.

Added:
  head/tools/regression/bin/sh/builtins/trap6.0   (contents, props changed)
Modified:
  head/bin/sh/trap.c

Modified: head/bin/sh/trap.c
==============================================================================
--- head/bin/sh/trap.c	Sun Jan 16 10:47:35 2011	(r217471)
+++ head/bin/sh/trap.c	Sun Jan 16 13:56:41 2011	(r217472)
@@ -79,6 +79,7 @@ static volatile sig_atomic_t gotsig[NSIG
 				/* indicates specified signal received */
 static int ignore_sigchld;	/* Used while handling SIGCHLD traps. */
 volatile sig_atomic_t gotwinch;
+static int last_trapsig;
 
 static int exiting;		/* exitshell() has been called */
 static int exiting_exitstatus;	/* value passed to exitshell() */
@@ -441,6 +442,7 @@ dotrap(void)
 					 */
 					if (i == SIGCHLD)
 						ignore_sigchld++;
+					last_trapsig = i;
 					savestatus = exitstatus;
 					evalstring(trap[i], 0);
 					exitstatus = savestatus;
@@ -495,9 +497,16 @@ exitshell_savedstatus(void)
 {
 	struct jmploc loc1, loc2;
 	char *p;
+	int sig = 0;
+	sigset_t sigs;
 
-	if (!exiting)
-		exiting_exitstatus = oexitstatus;
+	if (!exiting) {
+		if (in_dotrap && last_trapsig) {
+			sig = last_trapsig;
+			exiting_exitstatus = sig + 128;
+		} else
+			exiting_exitstatus = oexitstatus;
+	}
 	exitstatus = oexitstatus = exiting_exitstatus;
 	if (setjmp(loc1.loc)) {
 		goto l1;
@@ -515,5 +524,15 @@ l1:   handler = &loc2;			/* probably unn
 #if JOBS
 	setjobctl(0);
 #endif
-l2:   _exit(exiting_exitstatus);
+l2:
+	if (sig != 0 && sig != SIGSTOP && sig != SIGTSTP && sig != SIGTTIN &&
+	    sig != SIGTTOU) {
+		signal(sig, SIG_DFL);
+		sigemptyset(&sigs);
+		sigaddset(&sigs, sig);
+		sigprocmask(SIG_UNBLOCK, &sigs, NULL);
+		kill(getpid(), sig);
+		/* If the default action is to ignore, fall back to _exit(). */
+	}
+	_exit(exiting_exitstatus);
 }

Added: head/tools/regression/bin/sh/builtins/trap6.0
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/regression/bin/sh/builtins/trap6.0	Sun Jan 16 13:56:41 2011	(r217472)
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+v=$(
+	${SH} -c 'trap "echo ok; exit" USR1; kill -USR1 $$' &
+	# Suppress possible message about exit on signal
+	wait $! >/dev/null 2>&1
+)
+r=$(kill -l $?)
+[ "$v" = "ok" ] && { [ "$r" = "USR1" ] || [ "$r" = "usr1" ]; }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201101161356.p0GDuf9O065545>