From 5ae6ee36a954c208f9859b1596737b5e75fbef3f Mon Sep 17 00:00:00 2001 From: bdrewery Date: Sat, 18 Apr 2015 23:49:57 +0000 Subject: [PATCH] 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 --- bin/sh/sh.1 | 5 ++--- bin/sh/tests/builtins/Makefile | 2 ++ bin/sh/tests/builtins/trap15.0 | 5 +++++ bin/sh/tests/builtins/trap16.0 | 20 ++++++++++++++++++++ bin/sh/trap.c | 2 +- 5 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 bin/sh/tests/builtins/trap15.0 create mode 100644 bin/sh/tests/builtins/trap16.0 diff --git a/bin/sh/sh.1 b/bin/sh/sh.1 index b22a98f01132..e5707c0ff721 100644 --- a/bin/sh/sh.1 +++ b/bin/sh/sh.1 @@ -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 diff --git a/bin/sh/tests/builtins/Makefile b/bin/sh/tests/builtins/Makefile index 5f5da4a89077..ad39aacf1be5 100644 --- a/bin/sh/tests/builtins/Makefile +++ b/bin/sh/tests/builtins/Makefile @@ -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 diff --git a/bin/sh/tests/builtins/trap15.0 b/bin/sh/tests/builtins/trap15.0 new file mode 100644 index 000000000000..6b9857df3d1a --- /dev/null +++ b/bin/sh/tests/builtins/trap15.0 @@ -0,0 +1,5 @@ +# $FreeBSD$ + +(${SH} -c 'term(){ exit 5;}; trap term TERM; kill -TERM $$') & +wait >/dev/null 2>&1 $! +[ $? -eq 5 ] diff --git a/bin/sh/tests/builtins/trap16.0 b/bin/sh/tests/builtins/trap16.0 new file mode 100644 index 000000000000..3d70cce8a721 --- /dev/null +++ b/bin/sh/tests/builtins/trap16.0 @@ -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 diff --git a/bin/sh/trap.c b/bin/sh/trap.c index 4a185b4874f5..f562e2785a58 100644 --- a/bin/sh/trap.c +++ b/bin/sh/trap.c @@ -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 {