zsh-workers
 help / color / mirror / code / Atom feed
From: "Eduardo A. Bustamante López" <dualbus@gmail.com>
To: zsh-workers@zsh.org
Subject: Zsh does not follow POSIX when return is called during the action of a trap
Date: Wed, 12 Mar 2014 08:36:27 -0700	[thread overview]
Message-ID: <20140312153627.GA15209@dualbus.me> (raw)

Hi! I first reported this bug to bug-bash, but since it also applies
to zsh, I wanted you to know about it. I'll use the same report I
sent, since it's the same problem:



According to POSIX:

| The value of the special parameter '?' shall be set to n, an
| unsigned decimal integer, or to the exit status of the last command
| executed if n is not specified. If the value of n is greater than
| 255, the results are undefined. When return is executed in a trap
| action, the last command is considered to be the command that
| executed immediately preceding the trap action.

Source (EXIT STATUS section):
  
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#return


So, what I understand from this:

(1) When return is called without a numeric argument, the code
returned is that of the `last command'.

(2) The `last command' is defined as: ``[...] the command that
executed immediately preceding the trap action''.


Taking the SYNOPSIS for the trap builtin:

| trap n [condition...] 
| trap [action condition...]

and from DESCRIPTION:

| Each time trap is invoked, the action argument shall be processed in
| a manner equivalent to:
| 
| eval action

Source:
  http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#trap


So as I read it, `action' refers to the whole string.



Now, this means, taking the following pseudo-code:

|  trap '(exit BEFORE-RETURN); return' SIGNAL
|
|  fn() {
|    (exit BEFORE-ACTION); -block here waiting for signal-
|  }

If that script receives SIGNAL, it should return the BEFORE-ACTION
exit code, and not the BEFORE-RETURN exit code.



Testing this is a bit tricky, because there's no simple way of
blocking to wait for a signal in a way that it doesn't affect our
testing, so the bes I could come up with is this:


### begin test script
code='trap "(exit 2); return" USR1
f() {
    { echo; kill -USR1 $$; } | exit 3
    return 5
}

(exit 7); f
'

shells=(
    bash
    'bash --posix'
    ksh
    mksh
    dash
   'busybox sh'
    zsh
    jsh
)

for attempt in {1..1000}; do
    for shell in "address@hidden"; do
        printf '%s: %s\n' "$shell" "$($shell -c "$code"; echo $?)"
    done
done | sort | uniq -c
### end test script



And sample output from this script:

    969 bash: 2
     31 bash: 5
    979 bash --posix: 2
     21 bash --posix: 5
   1000 busybox sh: 5
    971 dash: 3
     29 dash: 5
    118 jsh: 3
    882 jsh: 5
      1 ksh: 0
    999 ksh: 3
    970 mksh: 3
     30 mksh: 5
      6 zsh: 2
    994 zsh: 3


Most of the time, zsh returns the correct code (3, BEFORE-ACTION),
but sometimes it returns 2, which is BEFORE-RETURN (and it should not).


The versions tested are:


bash --version|head -n1: 
  GNU bash, version 4.3.0(2)-release (x86_64-unknown-linux-gnu)
zsh --version|head -n1: 
  zsh 4.3.17 (x86_64-unknown-linux-gnu)
ksh --version|head -n1: 
    version         sh (AT&T Research) 93u+ 2012-02-29
mksh -c 'echo "$KSH_VERSION"': 
  @(#)MIRBSD KSH R40 2012/07/20 Debian-7
apt-cache policy dash|grep Installed: 
    Installed: 0.5.7-3
apt-cache policy busybox|grep Installed: 
    Installed: 1:1.20.0-7
head -n3 ~/local/src/heirloom-sh/CHANGES: 
  Release ...
* A bug in the supplied realloc() replacement could result in heap
  corruption. (No resulting failures have been observed with sh so far.)



Original bug report:
  http://lists.gnu.org/archive/html/bug-bash/2014-03/msg00053.html

-- 
Eduardo Alan Bustamante López


             reply	other threads:[~2014-03-12 15:36 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-12 15:36 Eduardo A. Bustamante López [this message]
2014-03-12 16:52 ` Bart Schaefer
2014-03-12 17:03   ` Peter Stephenson
2014-03-12 17:47     ` Eduardo A. Bustamante López
2014-03-12 17:49     ` Chet Ramey
2014-03-12 18:23       ` Peter Stephenson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140312153627.GA15209@dualbus.me \
    --to=dualbus@gmail.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

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