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
This commit is contained in:
Jilles Tjoelker 2020-08-28 15:35:45 +00:00
parent 27b293b022
commit 1cffe8b812
5 changed files with 27 additions and 2 deletions

View File

@ -134,6 +134,7 @@ main(int argc, char *argv[])
setstackmark(&smark);
setstackmark(&smark2);
procargs(argc, argv);
trap_init();
pwd_init(iflag);
INTON;
if (iflag)

View File

@ -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

View File

@ -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; exit 4; } &
exec 3>fifo1
kill -INT "$!"
kill -TERM "$!"
exec 3>&-
wait "$!"
r=$?
[ "$r" = 5 ]

View File

@ -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);
}

View File

@ -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;