trap: Implement POSIX.1-2008 trap reset behaviour (#2)
PATCH 1/1 trap: Implement POSIX.1-2008 trap reset behaviour (#2)
Clarifies a couple of issues with the previous patch, and expands on the rationale in the commit message. Sorry for the noise -- jperkin
POSIX.1-2008 for trap adds the following behaviour:
If the first operand is an unsigned decimal integer, the shell shall treat all operands as conditions, and shall reset each condition to the default value.
The interpretation of this behaviour differs among other shells. In the case where the first operand is an invalid signo:
bash-4.3.39(1), zsh-5.1.1:
$ trap echo 1 2 3
$ trap 100 1 2
$ trap
trap -- '100' SIGHUP
trap -- '100' SIGINT
trap -- 'echo' SIGQUITmksh-51:
$ trap echo 1 2 3
$ trap 100 1 2
mksh: trap: bad signal '100'
$ trap
trap -- echo QUITksh 93u+:
$ trap echo 1 2 3
$ trap 100 1 2
ksh: trap: 100: bad trap
$ trap
trap -- echo QUIT
trap -- echo INT
trap -- echo HUPAs the standard does not appear to specify that the first operand must be a valid signo for this behaviour to be triggered, we align with the ksh behaviour:
$ trap echo 1 2 3
$ trap 100 1 2
trap: 100: bad trap
$ trap
trap -- 'echo' HUP
trap -- 'echo' INT
trap -- 'echo' QUITAs for the case of the first operand being a signal name:
bash-4.3.39(1), mksh-51, ksh 93u+:
$ trap echo 1 2 3
$ trap HUP 2
$ trap
trap -- 'echo' SIGHUP
trap -- 'HUP' SIGINT
trap -- 'echo' SIGQUITzsh-5.1.1:
$ trap echo 1 2 3
$ trap HUP 2
$ trap
trap -- echo QUITHere we go with the majority and a strict interpretation of the standard, parsing it as a string rather than a signal:
$ trap echo 1 2 3
$ trap HUP 2
$ trap
trap -- 'echo' HUP
trap -- 'HUP' INT
trap -- 'echo' QUIT
---
src/trap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)src/trap.c +1 -1
@@ -112,7 +112,7 @@ trapcmd(int argc, char **argv) }return 0 ; } -if (!ap[1 ]) +if ((!ap[1 ]) || (is_number (*ap))) action =NULL ;else action = *ap++;
Signature · 4 lines
2.4.9 (Apple Git-60) -- Jonathan Perkin - Joyent, Inc. - www.joyent.com
Quoted 12 lines · Jonathan Perkin
Clarifies a couple of issues with the previous patch, and expands on the rationale in the commit message. Sorry for the noise -- jperkin
POSIX.1-2008 for trap adds the following behaviour:
If the first operand is an unsigned decimal integer, the shell shall treat all operands as conditions, and shall reset each condition to the default value.
The interpretation of this behaviour differs among other shells. In the case where the first operand is an invalid signo:
Quoted 8 lines
bash-4.3.39(1), zsh-5.1.1:
$ trap echo 1 2 3 $ trap 100 1 2 $ trap trap -- '100' SIGHUP trap -- '100' SIGINT trap -- 'echo' SIGQUIT
So dash's behaviour is the same as bash. I'm not changing this.
Cheers,
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Quoted 15 lines · * On 2015-12-08 at 08:25 GMT, Herbert Xu wrote:
Quoted 14 lines · Jonathan Perkin
Clarifies a couple of issues with the previous patch, and expands on the rationale in the commit message. Sorry for the noise -- jperkin
POSIX.1-2008 for trap adds the following behaviour:
If the first operand is an unsigned decimal integer, the shell shall treat all operands as conditions, and shall reset each condition to the default value.
The interpretation of this behaviour differs among other shells. In the case where the first operand is an invalid signo:
bash-4.3.39(1), zsh-5.1.1:
Quoted 8 lines
Quoted 6 lines
$ trap echo 1 2 3 $ trap 100 1 2 $ trap trap -- '100' SIGHUP trap -- '100' SIGINT trap -- 'echo' SIGQUITSo dash's behaviour is the same as bash. I'm not changing this.
Ok, that's fair enough. New patch below which supports the new behaviour but matches bash for all cases, as well as retaining historical dash behaviour for invalid signos.
1. First operand an integer but invalid signo:
bash-4.3.39(1), dash (without patch), dash (with patch)
$ trap 100 1 2; trap
trap -- '100' HUP
trap -- '100' INT2. First operand not an integer but valid signame:
bash-4.3.39(1), dash (without patch), dash (with patch)
$ trap HUP 2; trap
trap -- '100' HUP
trap -- 'HUP' INT
3. First operand an integer and valid signo:
dash (without patch)
$ trap 1 2; trap
trap -- '100' HUP
trap -- '1' INT
bash-4.3.39(1), dash (with patch)
$ trap 1 2; trap
[no output]
Hopefully that's acceptable. I've inlined most of the format-patch below, I didn't know if attachments are welcome to this list.
Cheers,
Signature · 16 lines
Subject: [PATCH] trap: Implement POSIX.1-2008 trap reset behaviour
POSIX.1-2008 for trap adds the following behaviour:
If the first operand is an unsigned decimal integer, the shell shall
treat all operands as conditions, and shall reset each condition to
the default value.
Historically dash has treated the first operand as an action. In order
not to change this behaviour, only valid signal numbers will trigger the
additional clause. This matches the behaviour of bash in this regard.
---
src/jobs.c | 4 ++--
src/trap.c | 9 +++++----
src/trap.h | 2 +-
3 files changed, 8 insertions(+), 7 deletions(-)src/jobs.c +2 -2
@@ -259,7 +259,7 @@ usage: }if (**++argv =='-' ) { - signo =decode_signal (*argv +1 ,1 ); + signo =decode_signal (*argv +1 ,1 ,0 );if (signo <0 ) {int c;
@@ -273,7 +273,7 @@ usage: list =1 ;break ;case 's' : - signo =decode_signal (optionarg,1 ); + signo =decode_signal (optionarg,1 ,0 );if (signo <0 ) { sh_error( "invalid signal number or name: %s",
src/trap.c +5 -4
@@ -112,12 +112,12 @@ trapcmd(int argc, char **argv) }return 0 ; } -if (!ap[1 ]) +if ((!ap[1 ]) || (decode_signal (*ap,0 ,1 )) >=0 ) action =NULL ;else action = *ap++;while (*ap) { -if ((signo =decode_signal (*ap,0 )) <0 ) { +if ((signo =decode_signal (*ap,0 ,0 )) <0 ) {outfmt (out2,"trap: %s: bad trap\n" , *ap);return 1 ; }
@@ -400,7 +400,7 @@ out:/* NOTREACHED */ } -int decode_signal (const char *string,int minsig) +int decode_signal (const char *string,int minsig,int numonly) {int signo;
@@ -410,7 +410,8 @@ int decode_signal(const char *string, int minsig)return -1 ; }return signo; - } + }else if (numonly) +return -1 ;for (signo = minsig; signo <NSIG ; signo++) {if (!strcasecmp (string, signal_names[signo])) {
src/trap.h +1 -1
@@ -49,7 +49,7 @@ void onsig(int);void dotrap (void );void setinteractive (int );void exitshell (void ) __attribute__((__noreturn__)); -int decode_signal (const char *,int ); +int decode_signal (const char *,int ,int );static inline int have_traps (void ) {
Signature · 4 lines
2.4.9 (Apple Git-60) -- Jonathan Perkin - Joyent, Inc. - www.joyent.com
Quoted 2 lines · Jonathan Perkin
Clarifies a couple of issues with the previous patch, and expands on the rationale in the commit message. Sorry for the noise -- jperkin
Thanks for the patch.
I've decided to do something similar to your final patch:
---8<---
Jonathan Perkin submitted a patch to fix the behaviour of trap when the first argument is an integer. Currently it is treated as a command while POSIX requires it to be treated as a signal.
This patch is based on his idea but instead of adding an extra argument to decode_signal I have added a new decode_signum helper.
src/trap.c +18 -7
@@ -79,6 +79,8 @@ int gotsigchld;extern char *signal_names[]; +static int decode_signum (const char *); +#ifdef mkinitINCLUDE "trap.h" INIT {
@@ -112,7 +114,7 @@ trapcmd(int argc, char **argv) }return 0 ; } -if (!ap[1 ]) +if (!ap[1 ] ||decode_signum (*ap) >=0 ) action =NULL ;else action = *ap++;
@@ -400,18 +402,27 @@ out:/* NOTREACHED */ } -int decode_signal (const char *string,int minsig) +static int decode_signum (const char *string) { -int signo; +int signo =-1 ;if (is_number (string)) { signo =atoi (string); -if (signo >=NSIG ) { -return -1 ; - } -return signo; +if (signo >=NSIG ) + signo =-1 ; } +return signo; +} + +int decode_signal (const char *string,int minsig) +{ +int signo; + + signo =decode_signum (string); +if (signo >=0 ) +return signo; +for (signo = minsig; signo <NSIG ; signo++) {if (!strcasecmp (string, signal_names[signo])) {return signo;
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt