From 1cffe8b812e5efda80d7c68dab86d2e1906ef088 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Fri, 28 Aug 2020 15:35:45 +0000 Subject: [PATCH] sh: Keep ignored SIGINT/SIGQUIT after set in a background job If job control is not enabled, a background job (... &) ignores SIGINT and SIGQUIT, but this can be reverted using the trap builtin in the same shell environment. Using the set builtin to change options would also revert SIGINT and SIGQUIT to their previous dispositions. This broke due to r317298. Calling setsignal() reverts the effect of ignoresig(). Reported by: bdrewery MFC after: 1 week --- bin/sh/main.c | 1 + bin/sh/tests/execution/Makefile | 1 + bin/sh/tests/execution/bg13.0 | 16 ++++++++++++++++ bin/sh/trap.c | 10 ++++++++-- bin/sh/trap.h | 1 + 5 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 bin/sh/tests/execution/bg13.0 diff --git a/bin/sh/main.c b/bin/sh/main.c index 8df24dba312e..cbe026e13640 100644 --- a/bin/sh/main.c +++ b/bin/sh/main.c @@ -134,6 +134,7 @@ main(int argc, char *argv[]) setstackmark(&smark); setstackmark(&smark2); procargs(argc, argv); + trap_init(); pwd_init(iflag); INTON; if (iflag) diff --git a/bin/sh/tests/execution/Makefile b/bin/sh/tests/execution/Makefile index c457c148b8f3..cfc21caf3791 100644 --- a/bin/sh/tests/execution/Makefile +++ b/bin/sh/tests/execution/Makefile @@ -19,6 +19,7 @@ ${PACKAGE}FILES+= bg9.0 ${PACKAGE}FILES+= bg10.0 bg10.0.stdout ${PACKAGE}FILES+= bg11.0 ${PACKAGE}FILES+= bg12.0 +${PACKAGE}FILES+= bg13.0 ${PACKAGE}FILES+= env1.0 ${PACKAGE}FILES+= fork1.0 ${PACKAGE}FILES+= fork2.0 diff --git a/bin/sh/tests/execution/bg13.0 b/bin/sh/tests/execution/bg13.0 new file mode 100644 index 000000000000..37a4ad864ded --- /dev/null +++ b/bin/sh/tests/execution/bg13.0 @@ -0,0 +1,16 @@ +# $FreeBSD$ + +T=`mktemp -d ${TMPDIR:-/tmp}/sh-test.XXXXXXXX` +trap 'rm -rf $T' 0 +cd $T || exit 3 +mkfifo fifo1 +# Use a trap, not the default action, since the shell may catch SIGINT and +# therefore its processing may be delayed. +{ set -C; trap 'exit 5' TERM; read dummy fifo1 +kill -INT "$!" +kill -TERM "$!" +exec 3>&- +wait "$!" +r=$? +[ "$r" = 5 ] diff --git a/bin/sh/trap.c b/bin/sh/trap.c index 1b9ab63f47cb..d7a98604c22c 100644 --- a/bin/sh/trap.c +++ b/bin/sh/trap.c @@ -474,14 +474,20 @@ dotrap(void) } +void +trap_init(void) +{ + setsignal(SIGINT); + setsignal(SIGQUIT); +} + + /* * Controls whether the shell is interactive or not based on iflag. */ void setinteractive(void) { - setsignal(SIGINT); - setsignal(SIGQUIT); setsignal(SIGTERM); } diff --git a/bin/sh/trap.h b/bin/sh/trap.h index 63d0bd5e70b1..fdc4b7a9683a 100644 --- a/bin/sh/trap.h +++ b/bin/sh/trap.h @@ -45,6 +45,7 @@ void ignoresig(int); int issigchldtrapped(void); void onsig(int); void dotrap(void); +void trap_init(void); void setinteractive(void); void exitshell(int) __dead2; void exitshell_savedstatus(void) __dead2;