about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--Doc/Zsh/options.yo9
-rw-r--r--Etc/NEWS5
-rw-r--r--Src/jobs.c9
-rw-r--r--Src/options.c3
-rw-r--r--Src/signals.c5
-rw-r--r--Src/zsh.h1
7 files changed, 35 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 944991cb6..57f2a519a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2004-04-19  Peter Stephenson  <pws@csr.com>
+
+	* zsh=users/7365: Doc/Zsh/options.yo, Src/jobs.c, Src/options.c,
+	Src/signals.c, Src/zsh.h, plus unposted Etc/NEWS hunk: new option
+	TRAPS_ASYNC, turn off to stop traps being run while waiting
+	for a child process.
+
 2004-04-18  Clint Adams  <clint@zsh.org>
 
 	* 19792: Completion/X/Command/_mplayer: complete .m2v and .m2p,
diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
index aa22b016f..7f398cac6 100644
--- a/Doc/Zsh/options.yo
+++ b/Doc/Zsh/options.yo
@@ -1189,6 +1189,14 @@ item(tt(TRANSIENT_RPROMPT))(
 Remove any right prompt from display when accepting a command
 line.  This may be useful with terminals with other cut/paste methods.
 )
+pindex(TRAPS_ASYNC)
+cindex(traps, asynchronous)
+item(tt(TRAPS_ASYNC) <C> <Z>)(
+While waiting for a program to exit, run traps immediately.  Otherwise
+the trap is run after the program has exited.  Note this does not affect
+the point at which traps are run for any case other than when the shell is
+waiting for a child process.
+)
 pindex(TYPESET_SILENT)
 item(tt(TYPESET_SILENT))(
 If this is unset, executing any of the `tt(typeset)' family of
@@ -1366,6 +1374,7 @@ endsitem()
 subsect(sh/ksh emulation set)
 startsitem()
 sitem(tt(-C))(em(NO_)CLOBBER)
+sitem(tt(-T))(TRAPS_ASYNC)
 sitem(tt(-X))(MARK_DIRS)
 sitem(tt(-a))(ALL_EXPORT)
 sitem(tt(-b))(NOTIFY)
diff --git a/Etc/NEWS b/Etc/NEWS
index d2e53ee1c..0e5983b80 100644
--- a/Etc/NEWS
+++ b/Etc/NEWS
@@ -19,6 +19,11 @@ Changes since zsh version 4.2.0
   unnecessary confusion if, for example, both DEBUG and EXIT traps
   were set.  The new behaviour is more compatible with other shells.
 
+- New option TRAPS_ASYNC which if set allows traps to run while the
+  shell is waiting for a child process.  This is the traditional zsh
+  behaviour; POSIX requires the option to be unset.  In sh/ksh
+  compatibility mode the option is turned off by default and the option
+  letter -T turns it on, for compatibility with FreeBSD sh.
 
 New features between zsh versions 4.0 and 4.2
 ---------------------------------------------
diff --git a/Src/jobs.c b/Src/jobs.c
index 0188989df..072a91744 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -994,7 +994,11 @@ zwaitjob(int job, int sig)
     int q = queue_signal_level();
     Job jn = jobtab + job;
 
-    dont_queue_signals();
+    queue_not_sigchld++;
+    if (isset(TRAPSASYNC))
+	dont_queue_signals();
+    else
+	queue_signals();
     child_block();		 /* unblocked during child_suspend() */
     if (jn->procs || jn->auxprocs) { /* if any forks were done         */
 	jn->stat |= STAT_LOCKED;
@@ -1026,6 +1030,9 @@ zwaitjob(int job, int sig)
     }
     child_unblock();
     restore_queue_signals(q);
+    if (!queueing_enabled)
+	run_queued_signals();
+    queue_not_sigchld--;
 }
 
 /* wait for running job to finish */
diff --git a/Src/options.c b/Src/options.c
index 359229a57..7fd9906ee 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -203,6 +203,7 @@ static struct optname optns[] = {
 {NULL, "singlelinezle",	      OPT_KSH,			 SINGLELINEZLE},
 {NULL, "sunkeyboardhack",     0,			 SUNKEYBOARDHACK},
 {NULL, "transientrprompt",    0,			 TRANSIENTRPROMPT},
+{NULL, "trapsasync",	      OPT_EMULATE|OPT_NONBOURNE, TRAPSASYNC},
 {NULL, "typesetsilent",	      OPT_EMULATE|OPT_BOURNE,	 TYPESETSILENT},
 {NULL, "unset",		      OPT_EMULATE|OPT_BSHELL,	 UNSET},
 {NULL, "verbose",	      0,			 VERBOSE},
@@ -346,7 +347,7 @@ static short kshletters[LAST_OPT - FIRST_OPT + 1] = {
     /* Q */  0,
     /* R */  0,
     /* S */  0,
-    /* T */  0,
+    /* T */  TRAPSASYNC,
     /* U */  0,
     /* V */  0,
     /* W */  0,
diff --git a/Src/signals.c b/Src/signals.c
index dbecdf20c..8939d1ba1 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -49,7 +49,7 @@ mod_export int nsigtrapped;
 /* Variables used by signal queueing */
 
 /**/
-mod_export int queueing_enabled, queue_front, queue_rear;
+mod_export int queueing_enabled, queue_front, queue_rear, queue_not_sigchld;
 /**/
 mod_export int signal_queue[MAX_QUEUE_SIZE];
 /**/
@@ -425,7 +425,8 @@ zhandler(int sig)
     }
 #endif
 
-    if (queueing_enabled) {           /* Are we queueing signals now?      */
+    /* Are we queueing signals now?      */
+    if (queueing_enabled && (sig != SIGCHLD || !queue_not_sigchld)) {
         int temp_rear = ++queue_rear % MAX_QUEUE_SIZE;
 
 	DPUTS(temp_rear == queue_front, "BUG: signal queue full");
diff --git a/Src/zsh.h b/Src/zsh.h
index a0b95bf42..523e8b2c3 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1523,6 +1523,7 @@ enum {
     SINGLELINEZLE,
     SUNKEYBOARDHACK,
     TRANSIENTRPROMPT,
+    TRAPSASYNC,
     TYPESETSILENT,
     UNSET,
     VERBOSE,