From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15623 invoked from network); 2 Oct 2001 14:19:53 -0000 Received: from sunsite.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 2 Oct 2001 14:19:53 -0000 Received: (qmail 3122 invoked by alias); 2 Oct 2001 14:19:43 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 15923 Received: (qmail 3091 invoked from network); 2 Oct 2001 14:19:40 -0000 From: Bart Schaefer Message-Id: <1011002141931.ZM24534@candle.brasslantern.com> Date: Tue, 2 Oct 2001 14:19:31 +0000 In-Reply-To: <19318.1002018234@csr.com> Comments: In reply to Peter Stephenson "Re: PATCH: test for trap EXIT fix." (Oct 2, 11:23am) References: <19318.1002018234@csr.com> X-Mailer: Z-Mail (5.0.0 30July97) To: zsh-workers@sunsite.dk (Zsh hackers list) Subject: Re: PATCH: test for trap EXIT fix. MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii On Oct 2, 11:23am, Peter Stephenson wrote: } } Bart Schaefer wrote: } > On Oct 1, 1:01pm, Peter Stephenson wrote: } > } } > } The comment notes the following behaviour: } > } } > } fn() { } > } ( trap 'print This is in the top-level function scope.' EXIT } > } exit } > } ) } > } } } > } > Wait ... why is that trap at the top-level function scope? It's inside a } > subshell. Shouldn't the subshell be its own scope? } } That's never happened before. We can introduce scopes for subshells, but } it's probably quite a lot of work. I don't really mean a true "scope"; but I'd be less surprised to find that fn() { trap 'print This is in the top-level function scope.' EXIT ( exit ) } did not run the trap. In the first example, what's the point of setting the trap inside the subshell if you don't mean to trap the exit of the subshell? } > zsh% trap 'print PS1-level' EXIT; (exit) #3 } > zsh% function TRAPEXIT { print PS1-level }; (exit) #4 } > PS1-level } } The odd difference between #3 and #4 seems to be deliberate, weirdly } enough. If you look at the top of entersubsh(), you will see traps are } usually cleared (cl == 2 implies this is not a `real' subshell, for some } definition of `not real' I haven't entirely worked out but which doesn't } apply in this case), but are left when the trap is a function: } } if (cl != 2) } for (sig = 0; sig < VSIGCOUNT; sig++) } if (!(sigtrapped[sig] & ZSIG_FUNC)) } unsettrap(sig); } } I can't imagine this is deliberately deliberate? It must have been } deliberate in some accidental fashion. Hmm, I'll bet it WAS deliberately deliberate. Look how bash behaves: bash2-2.03$ fn() { trap 'echo exiting' 0; (exit); } bash2-2.03$ fn bash2-2.03$ fn() { (trap 'echo exiting' 0; exit); } bash2-2.03$ fn exiting bash2-2.03$ I think somebody (possibly even PF) decided that exit traps should have worked all along the way the TRAPEXIT function works (case #4) but made `trap' work the way the Bourne shell works for compatibility. At the very least, I imagine that somebody wanted TRAPEXIT() { echo 'I am a function' } (functions) to print the definition of the TRAPEXIT function. QED. This should probably be documented somewhere. } Maybe there's a simple tweak to the code I introduced so this can be done } without a full extra layer of scoping. Can you explain to me why the subshell exits without ever leaving the function scope? Why doesn't it just exit from a forked copy of the function scope? Of course in that case we have to clear traps in all scopes on entry to the subshell, not just traps in the current scope, in order to preserve the Bourne shell behavior. Or something like that. -- Bart Schaefer Brass Lantern Enterprises http://www.well.com/user/barts http://www.brasslantern.com Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net