dash.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] trap: Implement POSIX.1-2008 trap reset behaviour (#2)
@ 2015-12-07 17:50 Jonathan Perkin
  2015-12-08  8:24 ` Herbert Xu
  2016-06-06 11:52 ` Herbert Xu
  0 siblings, 2 replies; 4+ messages in thread
From: Jonathan Perkin @ 2015-12-07 17:50 UTC (permalink / raw)
  To: dash

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' SIGQUIT

  mksh-51:

    $ trap echo 1 2 3
    $ trap 100 1 2
    mksh: trap: bad signal '100'
    $ trap
    trap -- echo QUIT

  ksh 93u+:

    $ trap echo 1 2 3
    $ trap 100 1 2
    ksh: trap: 100: bad trap
    $ trap
    trap -- echo QUIT
    trap -- echo INT
    trap -- echo HUP

As 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' QUIT

As 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' SIGQUIT

  zsh-5.1.1:

    $ trap echo 1 2 3
    $ trap HUP 2
    $ trap
    trap -- echo QUIT

Here 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(-)

diff --git a/src/trap.c b/src/trap.c
index 82d4263..3dc1949 100644
--- a/src/trap.c
+++ b/src/trap.c
@@ -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++;
-- 
2.4.9 (Apple Git-60)

-- 
Jonathan Perkin  -  Joyent, Inc.  -  www.joyent.com

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] trap: Implement POSIX.1-2008 trap reset behaviour (#2)
  2015-12-07 17:50 [PATCH] trap: Implement POSIX.1-2008 trap reset behaviour (#2) Jonathan Perkin
@ 2015-12-08  8:24 ` Herbert Xu
  2015-12-08  9:51   ` Jonathan Perkin
  2016-06-06 11:52 ` Herbert Xu
  1 sibling, 1 reply; 4+ messages in thread
From: Herbert Xu @ 2015-12-08  8:24 UTC (permalink / raw)
  To: Jonathan Perkin; +Cc: dash

Jonathan Perkin <jperkin@joyent.com> wrote:
> 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' SIGQUIT

So dash's behaviour is the same as bash.  I'm not changing this.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] trap: Implement POSIX.1-2008 trap reset behaviour (#2)
  2015-12-08  8:24 ` Herbert Xu
@ 2015-12-08  9:51   ` Jonathan Perkin
  0 siblings, 0 replies; 4+ messages in thread
From: Jonathan Perkin @ 2015-12-08  9:51 UTC (permalink / raw)
  To: Herbert Xu; +Cc: dash

* On 2015-12-08 at 08:25 GMT, Herbert Xu wrote:

> Jonathan Perkin <jperkin@joyent.com> wrote:
> > 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' SIGQUIT
> 
> So 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' INT

  2. 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,

-- 
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(-)

diff --git a/src/jobs.c b/src/jobs.c
index c2c2332..0b1ae79 100644
--- a/src/jobs.c
+++ b/src/jobs.c
@@ -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",
diff --git a/src/trap.c b/src/trap.c
index 82d4263..f2988bc 100644
--- a/src/trap.c
+++ b/src/trap.c
@@ -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])) {
diff --git a/src/trap.h b/src/trap.h
index 7573fd7..edbdb45 100644
--- a/src/trap.h
+++ b/src/trap.h
@@ -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)
 {
-- 
2.4.9 (Apple Git-60)

-- 
Jonathan Perkin  -  Joyent, Inc.  -  www.joyent.com

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: trap: Implement POSIX.1-2008 trap reset behaviour (#2)
  2015-12-07 17:50 [PATCH] trap: Implement POSIX.1-2008 trap reset behaviour (#2) Jonathan Perkin
  2015-12-08  8:24 ` Herbert Xu
@ 2016-06-06 11:52 ` Herbert Xu
  1 sibling, 0 replies; 4+ messages in thread
From: Herbert Xu @ 2016-06-06 11:52 UTC (permalink / raw)
  To: Jonathan Perkin; +Cc: dash

On Mon, Dec 07, 2015 at 05:50:47PM +0000, Jonathan Perkin wrote:
> 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.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

diff --git a/src/trap.c b/src/trap.c
index 82d4263..edb9938 100644
--- a/src/trap.c
+++ b/src/trap.c
@@ -79,6 +79,8 @@ int gotsigchld;
 
 extern char *signal_names[];
 
+static int decode_signum(const char *);
+
 #ifdef mkinit
 INCLUDE "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;
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-06-06 11:52 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-07 17:50 [PATCH] trap: Implement POSIX.1-2008 trap reset behaviour (#2) Jonathan Perkin
2015-12-08  8:24 ` Herbert Xu
2015-12-08  9:51   ` Jonathan Perkin
2016-06-06 11:52 ` Herbert Xu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).