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

Re: Weird exit caused in a trap DEBUG which sources a file.



On Fri, 1 Aug 2008 08:29:29 -0400
"Rocky Bernstein" <rocky.bernstein@xxxxxxxxx> wrote:
> Looks like the crucial change that makes zsh 4.3.5-dev and current SVN
> sources fail is an extra source after the trap DEBUG:

Thanks, this is what I needed.

The source code wasn't handling the variable that indicates a trap has told
us to return from a function properly.  The variable is only primed for
action if negative.  That's the init.c hunk.

The signals.c hunk is to save and restore trapreturn for nested trap
handlers.  I'm not sure it's necessary; I am sure it's not wrong and
prevents hostages to fortune.

The hairy trap tests still pass, which is good; it would be better to add
this as a test, too, which shouldn't be too hard as there's nothing here
that depends on external behaviour.

I've documented the variable trapreturn better.

Index: Src/exec.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/exec.c,v
retrieving revision 1.135
diff -u -r1.135 exec.c
--- Src/exec.c	31 Jul 2008 08:44:21 -0000	1.135
+++ Src/exec.c	1 Aug 2008 13:29:06 -0000
@@ -64,7 +64,23 @@
 /**/
 mod_export int errflag;
  
-/* Status of return from a trap */
+/*
+ * Status of return from a trap.
+ * This is only active if we are inside a trap, else its value
+ * is irrelevant.  It is initialised to -1 for a function trap and
+ * -2 for a non-function trap and if negative is decremented as
+ * we go deeper into functions and incremented as we come back up.
+ * The value is used to decide if an explicit "return" should cause
+ * a return from the caller of the trap; it does this by setting
+ * trapreturn to a status (i.e. a non-negative value).
+ *
+ * In summary, trapreturn is
+ * - zero unless we are in a trap
+ * - negative in a trap unless it has triggered.  Code uses this
+ *   to detect an active trap.
+ * - non-negative in a trap once it was triggered.  It should remain
+ *   non-negative until restored after execution of the trap.
+ */
  
 /**/
 int trapreturn;
Index: Src/init.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/init.c,v
retrieving revision 1.87
diff -u -r1.87 init.c
--- Src/init.c	31 Jul 2008 08:44:21 -0000	1.87
+++ Src/init.c	1 Aug 2008 13:29:06 -0000
@@ -191,7 +191,7 @@
 	    exit(lastval);
 	if (((!interact || sourcelevel) && errflag) || retflag)
 	    break;
-	if (trapreturn) {
+	if (trapreturn >= 0) {
 	    lastval = trapreturn;
 	    trapreturn = 0;
 	}
Index: Src/signals.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/signals.c,v
retrieving revision 1.47
diff -u -r1.47 signals.c
--- Src/signals.c	31 Jul 2008 08:44:21 -0000	1.47
+++ Src/signals.c	1 Aug 2008 13:29:06 -0000
@@ -1085,6 +1085,7 @@
     int trapret = 0;
     int obreaks = breaks;
     int oretflag = retflag;
+    int otrapreturn = trapreturn;
     int isfunc;
     int traperr;
 
@@ -1183,6 +1184,7 @@
 	trapret = trapreturn + 1;
     }
     traperr = errflag;
+    trapreturn = otrapreturn;
     execrestore();
     lexrestore();
 

-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070



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