summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/sh/trap.c27
-rw-r--r--tools/regression/bin/sh/builtins/trap6.09
2 files changed, 32 insertions, 4 deletions
diff --git a/bin/sh/trap.c b/bin/sh/trap.c
index d2e5308..048c75c 100644
--- a/bin/sh/trap.c
+++ b/bin/sh/trap.c
@@ -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;
-
- if (!exiting)
- exiting_exitstatus = oexitstatus;
+ int sig = 0;
+ sigset_t sigs;
+
+ 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 unnecessary */
#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);
}
diff --git a/tools/regression/bin/sh/builtins/trap6.0 b/tools/regression/bin/sh/builtins/trap6.0
new file mode 100644
index 0000000..bd2bf7e
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/trap6.0
@@ -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" ]; }
OpenPOWER on IntegriCloud