about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
authorBart Schaefer <barts@users.sourceforge.net>2011-08-14 18:34:27 +0000
committerBart Schaefer <barts@users.sourceforge.net>2011-08-14 18:34:27 +0000
commit516ea294b8645fa910200096098575c39a55547a (patch)
tree64c934a814f14f23dfafc75dbd2e7497095da1f5 /Src
parent8af2cbd1f213dc7864c84dae869a705d03cf83d5 (diff)
downloadzsh-516ea294b8645fa910200096098575c39a55547a.tar.gz
zsh-516ea294b8645fa910200096098575c39a55547a.tar.xz
zsh-516ea294b8645fa910200096098575c39a55547a.zip
29677: Do not allow external processes in a pipeline to become suspended
when the end of the pipe is controlled by a builtin in the current shell
which cannot itself become suspended.
Diffstat (limited to 'Src')
-rw-r--r--Src/exec.c2
-rw-r--r--Src/signals.c17
-rw-r--r--Src/zsh.h2
3 files changed, 16 insertions, 5 deletions
diff --git a/Src/exec.c b/Src/exec.c
index 569c41cf7..a9164bc64 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -2848,6 +2848,8 @@ execcmd(Estate state, int input, int output, int how, int last1)
 	jobtab[thisjob].stat |= STAT_CURSH;
 	if (!jobtab[thisjob].procs)
 	    jobtab[thisjob].stat |= STAT_NOPRINT;
+	if (is_builtin)
+	  jobtab[thisjob].stat |= STAT_BUILTIN;
     } else {
 	/* This is an exec (real or fake) for an external command.    *
 	 * Note that any form of exec means that the subshell is fake *
diff --git a/Src/signals.c b/Src/signals.c
index 81949843f..dd39158d0 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -490,14 +490,21 @@ wait_for_processes(void)
 	 * update it.
 	 */
 	if (findproc(pid, &jn, &pn, 0)) {
+	    if (((jn->stat & STAT_BUILTIN) ||
+		 (list_pipe && (jobtab[thisjob].stat & STAT_BUILTIN))) &&
+		WIFSTOPPED(status) && WSTOPSIG(status) == SIGTSTP) {
+		killjb(jn, SIGCONT);
+		zwarn("job can't be suspended");
+	    } else {
 #if defined(HAVE_WAIT3) && defined(HAVE_GETRUSAGE)
-	    struct timezone dummy_tz;
-	    gettimeofday(&pn->endtime, &dummy_tz);
-	    pn->status = status;
-	    pn->ti = ru;
+		struct timezone dummy_tz;
+		gettimeofday(&pn->endtime, &dummy_tz);
+		pn->status = status;
+		pn->ti = ru;
 #else
-	    update_process(pn, status);
+		update_process(pn, status);
 #endif
+	    }
 	    update_job(jn);
 	} else if (findproc(pid, &jn, &pn, 1)) {
 	    pn->status = status;
diff --git a/Src/zsh.h b/Src/zsh.h
index 62ab5ade3..e3141120f 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -907,6 +907,8 @@ struct job {
 #define STAT_ATTACH	(0x1000) /* delay reattaching shell to tty       */
 #define STAT_SUBLEADER  (0x2000) /* is super-job, but leader is sub-shell */
 
+#define STAT_BUILTIN    (0x4000) /* job at tail of pipeline is a builtin */
+
 #define SP_RUNNING -1		/* fake status for jobs currently running */
 
 struct timeinfo {