diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/exec.c | 16 | ||||
-rw-r--r-- | Src/jobs.c | 19 | ||||
-rw-r--r-- | Src/zsh.h | 1 |
3 files changed, 31 insertions, 5 deletions
diff --git a/Src/exec.c b/Src/exec.c index b076f4af9..c9c895940 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -949,9 +949,10 @@ execpline(Estate state, wordcode slcode, int how, int last1) /* If the super-job contains only the sub-shell, the sub-shell is the group leader. */ - if (!jn->procs->next || lpforked == 2) + if (!jn->procs->next || lpforked == 2) { jn->gleader = list_pipe_pid; - + jn->stat |= STAT_SUBLEADER; + } for (pn = jobtab[jn->other].procs; pn; pn = pn->next) if (WIFSTOPPED(pn->status)) break; @@ -971,14 +972,17 @@ execpline(Estate state, wordcode slcode, int how, int last1) lastwj = -1; } + errbrk_saved = 0; for (; !nowait;) { if (list_pipe_child) { jn->stat |= STAT_NOPRINT; makerunning(jn); } - if (!(jn->stat & STAT_LOCKED)) + if (!(jn->stat & STAT_LOCKED)) { + child_unblock(); + child_block(); waitjobs(); - + } if (list_pipe_child && jn->stat & STAT_DONE && lastval2 & 0200) @@ -1042,6 +1046,10 @@ execpline(Estate state, wordcode slcode, int how, int last1) list_pipe = 0; list_pipe_child = 1; opts[INTERACTIVE] = 0; + if (errbrk_saved) { + errflag = prev_errflag; + breaks = prev_breaks; + } break; } } diff --git a/Src/jobs.c b/Src/jobs.c index e66d3b3fd..d519da00c 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -64,7 +64,13 @@ struct tms shtms; /**/ int ttyfrozen; - + +/* Previous values of errflag and breaks if the signal handler had to + * change them. And a flag saying if it did that. */ + +/**/ +int prev_errflag, prev_breaks, errbrk_saved; + static struct timeval dtimeval, now; /* Diff two timevals for elapsed-time computations */ @@ -311,6 +317,11 @@ update_job(Job jn) /* If we have `foo|while true; (( x++ )); done', and hit * ^C, we have to stop the loop, too. */ if ((val & 0200) && inforeground == 1) { + if (!errbrk_saved) { + errbrk_saved = 1; + prev_breaks = breaks; + prev_errflag = errflag; + } breaks = loops; errflag = 1; inerrflush(); @@ -322,6 +333,11 @@ update_job(Job jn) } } } else if (list_pipe && (val & 0200) && inforeground == 1) { + if (!errbrk_saved) { + errbrk_saved = 1; + prev_breaks = breaks; + prev_errflag = errflag; + } breaks = loops; errflag = 1; inerrflush(); @@ -1296,6 +1312,7 @@ bin_fg(char *name, char **argv, char *ops, int func) thisjob = job; if ((jobtab[job].stat & STAT_SUPERJOB) && ((!jobtab[job].procs->next || + (jobtab[job].stat & STAT_SUBLEADER) || killpg(jobtab[job].gleader, 0) == -1)) && jobtab[jobtab[job].other].gleader) attachtty(jobtab[jobtab[job].other].gleader); diff --git a/Src/zsh.h b/Src/zsh.h index 4be365901..3ad91b922 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -636,6 +636,7 @@ struct job { #define STAT_NOSTTY (1<<11) /* the tty settings are not inherited */ /* from this job when it exits. */ #define STAT_ATTACH (1<<12) /* delay reattaching shell to tty */ +#define STAT_SUBLEADER (1<<13) /* is super-job, but leader is sub-shell */ #define SP_RUNNING -1 /* fake status for jobs currently running */ |