From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4403 invoked from network); 2 Oct 2005 04:41:11 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 2 Oct 2005 04:41:11 -0000 Received: (qmail 83159 invoked from network); 2 Oct 2005 04:41:04 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 2 Oct 2005 04:41:04 -0000 Received: (qmail 12021 invoked by alias); 2 Oct 2005 04:41:00 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 21799 Received: (qmail 12010 invoked from network); 2 Oct 2005 04:40:59 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 2 Oct 2005 04:40:59 -0000 Received: (qmail 82863 invoked from network); 2 Oct 2005 04:40:59 -0000 Received: from vms048pub.verizon.net (206.46.252.48) by a.mx.sunsite.dk with SMTP; 2 Oct 2005 04:40:57 -0000 Received: from candle.brasslantern.com ([71.116.81.225]) by vms048.mailsrvcs.net (Sun Java System Messaging Server 6.2 HotFix 0.04 (built Dec 24 2004)) with ESMTPA id <0INP00JYEUC7VWJ0@vms048.mailsrvcs.net> for zsh-workers@sunsite.dk; Sat, 01 Oct 2005 23:40:56 -0500 (CDT) Received: from candle.brasslantern.com (IDENT:schaefer@localhost [127.0.0.1]) by candle.brasslantern.com (8.12.11/8.12.11) with ESMTP id j924erx5028375; Sat, 01 Oct 2005 21:40:54 -0700 Received: (from schaefer@localhost) by candle.brasslantern.com (8.12.11/8.12.11/Submit) id j924er1b028374; Sat, 01 Oct 2005 21:40:53 -0700 Date: Sun, 02 Oct 2005 04:40:52 +0000 From: Bart Schaefer Subject: Re: Exception handling and "trap" vs. TRAPNAL() In-reply-to: <20051001202856.GA134@DervishD> To: DervishD Cc: Peter Stephenson , zsh-workers@sunsite.dk Message-id: <1051002044052.ZM28373@candle.brasslantern.com> MIME-version: 1.0 X-Mailer: Z-Mail (5.0.0 30July97) Content-type: text/plain; charset=us-ascii References: <20050929200741.GA1156@DervishD> <20050930124130.45eb0463.pws@csr.com> <20051001153756.GA12183@DervishD> <1051001183818.ZM27904@candle.brasslantern.com> <20051001202856.GA134@DervishD> Comments: In reply to DervishD "Re: Exception handling and "trap" vs. TRAPNAL()" (Oct 1, 10:28pm) X-Spam-Checker-Version: SpamAssassin 3.0.4 (2005-06-05) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.0.4 On Oct 1, 10:28pm, DervishD wrote: } } I am still not sure whether this is a bug or a feature: } } trap 'false' DEBUG } } true } [[ $? -eq 1 ]] && print "What?" } } This snippet doesn't print anything, and won't do even if using } TRAPDEBUG and "return 1" instead of "false". Guess what. The bit of documentation that PWS quoted earlier is significantly at odds with the actual implementation. Here's that paragraph again: The return status from the function is handled specially. If it is zero, the signal is assumed to have been handled, and execution continues normally. So far we're right on the mark. Otherwise, the normal effect of the signal is produced; This is clearly inaccurate. If it were accurate, a non-zero return from TRAPHUP, TRAPABRT, or TRAPALRM (among others) ought to cause the shell to exit. This demonstrably does not happen. What *does* happen is that all levels of nested loop are broken (as if by the "break N" command with a sufficiently large N) and the shell is forced to behave as if a shell-level error occurred. (I'll note in passing that it actually has to be a GREATER THAN zero return value, not just non-zero; "return -1" doesn't cause any of the effects discussed here. But this bit of doc is already so far wrong that signedness makes little difference.) However, this effect is only achieved in two cases: (1) An explicit "return" command is used; it's a side-effect of the "return" builtin that the value of $? is recorded as the return value of the trap. (2) The TRAPNAL function itself exits with a shell-level error, such as a syntax error or an assignment to a read-only variable. Merely falling off the end of the function with $? > 0 is not sufficient. It's my contention that case (2) above is an oddball. It ought to behave the same way for "TRAPNAL() { ... }" and "trap ... NAL". That it does not is because the same local variable is overloaded to mean both "$? > 0 was true" and "error condition was true", not because of some strange special-case. if this causes execution to terminate, the status returned to the shell is the status returned from the function. This is also demonstrably wrong. Both cases above cause the return status to be set via the "behave as if a shell-level error occurred" reaction, so usually $? == 1. The side-effect of "return" on $? lasts only long enough to set up the forced error, then is erased as part of unwinding the trap context. In fact, ONLY in the case of "trap 'return X' NAL" is $? = X caused to happen, and that's because the trap executes in the context of the caller and forces the caller itself to return. This behavior of the return builtin in an "inline trap" is not documented anywhere as far as I can tell, but you can watch it in action (and badly cripple your shell) by writing -- trap return DEBUG -- and then attempting to execute any function that has more than one command in the body. A much more accurate description of the behavior of TRAPNAL can be found under the "return" command entry: If return was executed from a trap in a TRAPNAL function, the effect is different for zero and non-zero return status. With zero status (or after an implicit return at the end of the trap), the shell will return to whatever it was previously processing; with a non-zero status, the shell will behave as interrupted except that the return status of the trap is retained. Aha! "Behave as if interrupted" NOT "the normal effect of the signal." The doc under "TRAPNAL" needs to be repaired. (Here's another case of zsh code overloading a variable; "interrupt" and "shell-level error" are indistinguishable after a certain point.)