about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2004-03-25 10:07:12 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2004-03-25 10:07:12 +0000
commit83b0fd36740bd78d6058be58115ff688796a922a (patch)
tree38c3265238a2d0c8d87998d4442f981c78a4f31f
parent8de7436fc07454e2f5307c00ad99ee19d0baf853 (diff)
downloadzsh-83b0fd36740bd78d6058be58115ff688796a922a.tar.gz
zsh-83b0fd36740bd78d6058be58115ff688796a922a.tar.xz
zsh-83b0fd36740bd78d6058be58115ff688796a922a.zip
19682: Don't run ZERR, DEBUG or EXIT traps inside other traps.
-rw-r--r--ChangeLog6
-rw-r--r--Doc/Zsh/builtins.yo2
-rw-r--r--Etc/NEWS13
-rw-r--r--Src/signals.c24
4 files changed, 40 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index f83836078..64d5ea989 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2004-03-25  Peter Stephenson  <pws@csr.com>
+
+	* 19682: Doc/Zsh/builtins.yo, Etc/NEWS, Src/signals.c: Don't
+	run ZERR, DEBUG or EXIT traps inside other traps; caused confusion
+	and incompatibility.
+
 2004-03-24  Peter Stephenson  <pws@csr.com>
 
 	* 19674 plus unposted changes suggested in 19676:
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 3f6f3c450..363115297 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -1116,6 +1116,8 @@ If var(sig) is tt(0) or tt(EXIT)
 and the tt(trap) statement is not executed inside the body of a function,
 then the command var(arg) is executed when the shell terminates.
 
+tt(ZERR), tt(DEBUG) and tt(EXIT) traps are not executed inside other traps.
+
 The tt(trap) command with no arguments prints a list of commands
 associated with each signal.
 
diff --git a/Etc/NEWS b/Etc/NEWS
index 654857457..d2e53ee1c 100644
--- a/Etc/NEWS
+++ b/Etc/NEWS
@@ -5,14 +5,19 @@ CHANGES FROM PREVIOUS VERSIONS OF ZSH
 Changes since zsh version 4.2.0
 -------------------------------
 
-The zftp module supports ports following the hostname in the normal suffix
-notation, `host:port'.  This requires IPv6 colon-style addresses to be
-specified in suitably quoted square brackets, for example:
+- The zftp module supports ports following the hostname in the normal suffix
+  notation, `host:port'.  This requires IPv6 colon-style addresses to be
+  specified in suitably quoted square brackets, for example:
 
   zftp open '[f000::baaa]'
   zftp open '[f000::baaa]:ftp'
 
-(the two are equivalent).
+  (the two are equivalent).
+
+- Special traps, those that don't correspond to signals, i.e. ZERR, DEBUG
+  and EXIT are no longer executed inside other traps.  This caused
+  unnecessary confusion if, for example, both DEBUG and EXIT traps
+  were set.  The new behaviour is more compatible with other shells.
 
 
 New features between zsh versions 4.0 and 4.2
diff --git a/Src/signals.c b/Src/signals.c
index affb5379b..dbecdf20c 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -932,7 +932,10 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
     int trapret = 0;
     int obreaks = breaks;
     int isfunc;
- 
+
+    /* Are we already executing a trap? */
+    static int intrap;
+
     /* if signal is being ignored or the trap function		      *
      * is NULL, then return					      *
      *								      *
@@ -946,6 +949,24 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
     if ((*sigtr & ZSIG_IGNORED) || !sigfn || errflag)
         return;
 
+    /*
+     * Never execute special (synchronous) traps inside other traps.
+     * This can cause unexpected code execution when more than one
+     * of these is set.
+     *
+     * The down side is that it's harder to debug traps.  I don't think
+     * that's a big issue.
+     */
+    if (intrap) {
+	switch (sig) {
+	case SIGEXIT:
+	case SIGDEBUG:
+	case SIGZERR:
+	    return;
+	}
+    }
+
+    intrap++;
     *sigtr |= ZSIG_IGNORED;
 
     lexsave();
@@ -1023,6 +1044,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
 
     if (*sigtr != ZSIG_IGNORED)
 	*sigtr &= ~ZSIG_IGNORED;
+    intrap--;
 }
 
 /* Standard call to execute a trap for a given signal. */