From 516ea294b8645fa910200096098575c39a55547a Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 14 Aug 2011 18:34:27 +0000 Subject: 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. --- ChangeLog | 9 ++++++++- Src/exec.c | 2 ++ Src/signals.c | 17 ++++++++++++----- Src/zsh.h | 2 ++ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 95354095f..d9e63f36e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,13 @@ * unposted: Src/jobs.c: fix capitalized word in the middle of a sentence. +2011-08-14 Barton E. Schaefer + + * 29677: Src/exec.c, Src/signals.c, Src/zsh.h: flag jobs that are + builtins running in the current shell, and if they control a + pipeline, do not allow the external processes in that pipeline to + become suspended when the foreground shell cannot suspend. + 2011-08-11 Peter Stephenson * Src/Modules/datetime.mdd: unposted: also fix the autofeatures. @@ -15247,5 +15254,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5426 $ +* $Revision: 1.5427 $ ***************************************************** 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 { -- cgit 1.4.1