sh: Fix the trap builtin to be POSIX-compliant for 'trap exit SIG' and 'trap n n...'.

The parser considered 'trap exit INT' to reset the default for both EXIT and
INT. This beahvior is not POSIX compliant. This was avoided if a value was
specified for 'exit', but then disallows exiting with the signal received. A
possible workaround is using ' exit'.

However POSIX does allow this type of behavior if the parameters are all
integers. Fix the handling for this and clarify its support in the manpage
since it is specifically allowed by POSIX.

Differential Revision:	https://reviews.freebsd.org/D2325
Reviewed by:	jilles
MFC after:	2 weeks
This commit is contained in:
Bryan Drewery 2015-04-18 23:49:57 +00:00
parent 4c5ccd08a3
commit a59f817491
5 changed files with 30 additions and 4 deletions

View File

@ -32,7 +32,7 @@
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
.\" $FreeBSD$
.\"
.Dd February 22, 2015
.Dd April 18, 2015
.Dt SH 1
.Os
.Sh NAME
@ -2574,8 +2574,7 @@ the former causes the specified signal to be ignored
and the latter causes the default action to be taken.
Omitting the
.Ar action
is another way to request the default action, for compatibility reasons this
usage is not recommended though.
and using only signal numbers is another way to request the default action.
In a subshell or utility environment,
the shell resets trapped (but not ignored) signals to the default action.
The

View File

@ -137,6 +137,8 @@ FILES+= trap11.0
FILES+= trap12.0
FILES+= trap13.0
FILES+= trap14.0
FILES+= trap15.0
FILES+= trap16.0
FILES+= trap2.0
FILES+= trap3.0
FILES+= trap4.0

View File

@ -0,0 +1,5 @@
# $FreeBSD$
(${SH} -c 'term(){ exit 5;}; trap term TERM; kill -TERM $$') &
wait >/dev/null 2>&1 $!
[ $? -eq 5 ]

View File

@ -0,0 +1,20 @@
# $FreeBSD$
traps=$(${SH} -c 'trap "echo bad" 0; trap - 0; trap')
[ -z "$traps" ] || exit 1
traps=$(${SH} -c 'trap "echo bad" 0; trap "" 0; trap')
expected_traps=$(${SH} -c 'trap "" EXIT; trap')
[ "$traps" = "$expected_traps" ] || exit 2
traps=$(${SH} -c 'trap "echo bad" 0; trap 0; trap')
[ -z "$traps" ] || exit 3
traps=$(${SH} -c 'trap "echo bad" 0; trap -- 0; trap')
[ -z "$traps" ] || exit 4
traps=$(${SH} -c 'trap "echo bad" 0 1 2; trap - 0 1 2; trap')
[ -z "$traps" ] || exit 5
traps=$(${SH} -c 'trap "echo bad" 0 1 2; trap "" 0 1 2; trap')
expected_traps=$(${SH} -c 'trap "" EXIT HUP INT; trap')
[ "$traps" = "$expected_traps" ] || exit 6
traps=$(${SH} -c 'trap "echo bad" 0 1 2; trap 0 1 2; trap')
[ -z "$traps" ] || exit 7
traps=$(${SH} -c 'trap "echo bad" 0 1 2; trap -- 0 1 2; trap')
[ -z "$traps" ] || exit 8

View File

@ -183,7 +183,7 @@ trapcmd(int argc __unused, char **argv)
return 0;
}
action = NULL;
if (*argv && sigstring_to_signum(*argv) == -1) {
if (*argv && !is_number(*argv)) {
if (strcmp(*argv, "-") == 0)
argv++;
else {