From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23154 invoked by alias); 12 Mar 2014 15:36:41 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 32474 Received: (qmail 27796 invoked from network); 12 Mar 2014 15:36:36 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW, T_TO_NO_BRKTS_FREEMAIL autolearn=ham version=3.3.2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:subject:message-id:mime-version:content-type :content-disposition:content-transfer-encoding:user-agent; bh=5/3hezQJa+kUmNN0JGklkIfgpI2+KQW96EqoU5U3Z1A=; b=0n52G9z+SZcb7QM/TqbGhfPQ/SBy8fMRbFnUrWNOv/8f6yJQihjcc6ZQrb+1m/G3sp GZ8Mi8g4xvs2NP7xcMDr4k5+YZnSTsZnUJDgwpGZBNS5MkoToZjKrGFIgYekhmVMPaXv fnQUGiE+hOmnnQCvFF6K3dG4Z0QceyXMuwHOVddpVgeWt4REiSLX7a7LBsXHHOTSnSMt wteO7q021IILzp2FprscZjvN9uIS8AkbDw0fmHoz3yf6hVjvipU40+lJjPLvVzod19OX HzXRaXa/nQD0ZWKwvwL4uK1Osmjet+Z0QL21lPOfp+xNkL/zzvLMDjDiRtLoxyzNUfZY 8eSg== X-Received: by 10.68.178.229 with SMTP id db5mr5826021pbc.97.1394638590843; Wed, 12 Mar 2014 08:36:30 -0700 (PDT) Date: Wed, 12 Mar 2014 08:36:27 -0700 From: Eduardo =?utf-8?Q?A=2E_Bustamante_L=C3=B3pez?= To: zsh-workers@zsh.org Subject: Zsh does not follow POSIX when return is called during the action of a trap Message-ID: <20140312153627.GA15209@dualbus.me> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit User-Agent: Mutt/1.5.21 (2010-09-15) 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