Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: PATCH: test for trap EXIT fix.

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

	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

} > 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

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

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   

Messages sorted by: Reverse Date, Date, Thread, Author