|
|
ebecab |
From bbeb06a37ba58f6905803d32a26fb00953459301 Mon Sep 17 00:00:00 2001
|
|
|
ebecab |
From: "Barton E. Schaefer" <schaefer@zsh.org>
|
|
|
ebecab |
Date: Thu, 20 Mar 2014 07:56:30 -0700
|
|
|
ebecab |
Subject: [PATCH 1/8] 32500: handle interrupts during pattern matching
|
|
|
ebecab |
|
|
|
ebecab |
Upstream-commit: 8672d19f0c0f25569e233bbd466b6c39f60c7a55
|
|
|
ebecab |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
ebecab |
---
|
|
|
ebecab |
Src/pattern.c | 8 +++++++-
|
|
|
ebecab |
1 file changed, 7 insertions(+), 1 deletion(-)
|
|
|
ebecab |
|
|
|
ebecab |
diff --git a/Src/pattern.c b/Src/pattern.c
|
|
|
ebecab |
index b74a08a..b93b064 100644
|
|
|
ebecab |
--- a/Src/pattern.c
|
|
|
ebecab |
+++ b/Src/pattern.c
|
|
|
ebecab |
@@ -2128,6 +2128,8 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalen,
|
|
|
ebecab |
|
|
|
ebecab |
return ret;
|
|
|
ebecab |
} else {
|
|
|
ebecab |
+ int q = queue_signal_level();
|
|
|
ebecab |
+
|
|
|
ebecab |
/*
|
|
|
ebecab |
* Test for a `must match' string, unless we're scanning for a match
|
|
|
ebecab |
* in which case we don't need to do this each time.
|
|
|
ebecab |
@@ -2175,6 +2177,8 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalen,
|
|
|
ebecab |
|
|
|
ebecab |
patinput = patinstart;
|
|
|
ebecab |
|
|
|
ebecab |
+ dont_queue_signals();
|
|
|
ebecab |
+
|
|
|
ebecab |
if (patmatch((Upat)progstr)) {
|
|
|
ebecab |
/*
|
|
|
ebecab |
* we were lazy and didn't save the globflags if an exclusion
|
|
|
ebecab |
@@ -2311,6 +2315,8 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalen,
|
|
|
ebecab |
} else
|
|
|
ebecab |
ret = 0;
|
|
|
ebecab |
|
|
|
ebecab |
+ restore_queue_signals(q);
|
|
|
ebecab |
+
|
|
|
ebecab |
if (tryalloced)
|
|
|
ebecab |
zfree(tryalloced, unmetalen + unmetalenp);
|
|
|
ebecab |
|
|
|
ebecab |
@@ -2390,7 +2396,7 @@ patmatch(Upat prog)
|
|
|
ebecab |
zrange_t from, to, comp;
|
|
|
ebecab |
patint_t nextch;
|
|
|
ebecab |
|
|
|
ebecab |
- while (scan) {
|
|
|
ebecab |
+ while (scan && !errflag) {
|
|
|
ebecab |
next = PATNEXT(scan);
|
|
|
ebecab |
|
|
|
ebecab |
if (!globdots && P_NOTDOT(scan) && patinput == patinstart &&
|
|
|
ebecab |
--
|
|
|
ebecab |
2.5.0
|
|
|
ebecab |
|
|
|
ebecab |
|
|
|
ebecab |
From c3eeba82d560005d830862dace8d771e712693e6 Mon Sep 17 00:00:00 2001
|
|
|
ebecab |
From: "Barton E. Schaefer" <schaefer@zsh.org>
|
|
|
ebecab |
Date: Sun, 9 Aug 2015 00:50:36 -0700
|
|
|
ebecab |
Subject: [PATCH 2/8] 36022 fix bug that some loop constructs could not be
|
|
|
ebecab |
interrupted, revise signal queueing
|
|
|
ebecab |
|
|
|
ebecab |
There are two underlying ideas here: (1) Keeping signals queued around
|
|
|
ebecab |
anything that's doing memory management (including push/pop of the heap)
|
|
|
ebecab |
has become crucial. (2) Anytime the shell is going to run a command, be
|
|
|
ebecab |
it buitin or external, it must be both safe and necessary to process any
|
|
|
ebecab |
queued signals, so that the apparent order of signal arrival and command
|
|
|
ebecab |
execution is preserved.
|
|
|
ebecab |
|
|
|
ebecab |
Upstream-commit: 9958684574bf8b0ecec6983cca57f3fa3dd7cd63
|
|
|
ebecab |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
ebecab |
---
|
|
|
ebecab |
Src/exec.c | 43 ++++++++++++++++++++++++++++++++++++++-----
|
|
|
ebecab |
Src/init.c | 5 +++++
|
|
|
ebecab |
Src/input.c | 9 +++++++++
|
|
|
ebecab |
Src/loop.c | 36 ++++++++++++++++++++++++++++++++++--
|
|
|
ebecab |
Src/parse.c | 8 ++++++++
|
|
|
ebecab |
Src/signals.c | 8 ++++++--
|
|
|
ebecab |
6 files changed, 100 insertions(+), 9 deletions(-)
|
|
|
ebecab |
|
|
|
ebecab |
diff --git a/Src/exec.c b/Src/exec.c
|
|
|
ebecab |
index 7817a64..cff1a24 100644
|
|
|
ebecab |
--- a/Src/exec.c
|
|
|
ebecab |
+++ b/Src/exec.c
|
|
|
ebecab |
@@ -1108,8 +1108,12 @@ execsimple(Estate state)
|
|
|
ebecab |
fflush(xtrerr);
|
|
|
ebecab |
}
|
|
|
ebecab |
lv = (errflag ? errflag : cmdoutval);
|
|
|
ebecab |
- } else
|
|
|
ebecab |
+ } else {
|
|
|
ebecab |
+ int q = queue_signal_level();
|
|
|
ebecab |
+ dont_queue_signals();
|
|
|
ebecab |
lv = (execfuncs[code - WC_CURSH])(state, 0);
|
|
|
ebecab |
+ restore_queue_signals(q);
|
|
|
ebecab |
+ }
|
|
|
ebecab |
|
|
|
ebecab |
thisjob = otj;
|
|
|
ebecab |
|
|
|
ebecab |
@@ -1141,6 +1145,8 @@ execlist(Estate state, int dont_change_job, int exiting)
|
|
|
ebecab |
*/
|
|
|
ebecab |
int oldnoerrexit = noerrexit;
|
|
|
ebecab |
|
|
|
ebecab |
+ queue_signals();
|
|
|
ebecab |
+
|
|
|
ebecab |
cj = thisjob;
|
|
|
ebecab |
old_pline_level = pline_level;
|
|
|
ebecab |
old_list_pipe = list_pipe;
|
|
|
ebecab |
@@ -1391,6 +1397,8 @@ sublist_done:
|
|
|
ebecab |
/* Make sure this doesn't get executed again. */
|
|
|
ebecab |
sigtrapped[SIGEXIT] = 0;
|
|
|
ebecab |
}
|
|
|
ebecab |
+
|
|
|
ebecab |
+ unqueue_signals();
|
|
|
ebecab |
}
|
|
|
ebecab |
|
|
|
ebecab |
/* Execute a pipeline. *
|
|
|
ebecab |
@@ -1419,6 +1427,14 @@ execpline(Estate state, wordcode slcode, int how, int last1)
|
|
|
ebecab |
else if (slflags & WC_SUBLIST_NOT)
|
|
|
ebecab |
last1 = 0;
|
|
|
ebecab |
|
|
|
ebecab |
+ /* If trap handlers are allowed to run here, they may start another
|
|
|
ebecab |
+ * external job in the middle of us starting this one, which can
|
|
|
ebecab |
+ * result in jobs being reaped before their job table entries have
|
|
|
ebecab |
+ * been initialized, which in turn leads to waiting forever for
|
|
|
ebecab |
+ * jobs that no longer exist. So don't do that.
|
|
|
ebecab |
+ */
|
|
|
ebecab |
+ queue_signals();
|
|
|
ebecab |
+
|
|
|
ebecab |
pj = thisjob;
|
|
|
ebecab |
ipipe[0] = ipipe[1] = opipe[0] = opipe[1] = 0;
|
|
|
ebecab |
child_block();
|
|
|
ebecab |
@@ -1431,6 +1447,7 @@ execpline(Estate state, wordcode slcode, int how, int last1)
|
|
|
ebecab |
*/
|
|
|
ebecab |
if ((thisjob = newjob = initjob()) == -1) {
|
|
|
ebecab |
child_unblock();
|
|
|
ebecab |
+ unqueue_signals();
|
|
|
ebecab |
return 1;
|
|
|
ebecab |
}
|
|
|
ebecab |
if (how & Z_TIMED)
|
|
|
ebecab |
@@ -1486,6 +1503,7 @@ execpline(Estate state, wordcode slcode, int how, int last1)
|
|
|
ebecab |
else
|
|
|
ebecab |
spawnjob();
|
|
|
ebecab |
child_unblock();
|
|
|
ebecab |
+ unqueue_signals();
|
|
|
ebecab |
/* Executing background code resets shell status */
|
|
|
ebecab |
return lastval = 0;
|
|
|
ebecab |
} else {
|
|
|
ebecab |
@@ -1543,15 +1561,18 @@ execpline(Estate state, wordcode slcode, int how, int last1)
|
|
|
ebecab |
}
|
|
|
ebecab |
if (!(jn->stat & STAT_LOCKED)) {
|
|
|
ebecab |
updated = hasprocs(thisjob);
|
|
|
ebecab |
- waitjobs();
|
|
|
ebecab |
+ waitjobs(); /* deals with signal queue */
|
|
|
ebecab |
child_block();
|
|
|
ebecab |
} else
|
|
|
ebecab |
updated = 0;
|
|
|
ebecab |
if (!updated &&
|
|
|
ebecab |
list_pipe_job && hasprocs(list_pipe_job) &&
|
|
|
ebecab |
!(jobtab[list_pipe_job].stat & STAT_STOPPED)) {
|
|
|
ebecab |
+ int q = queue_signal_level();
|
|
|
ebecab |
child_unblock();
|
|
|
ebecab |
+ dont_queue_signals();
|
|
|
ebecab |
child_block();
|
|
|
ebecab |
+ restore_queue_signals(q);
|
|
|
ebecab |
}
|
|
|
ebecab |
if (list_pipe_child &&
|
|
|
ebecab |
jn->stat & STAT_DONE &&
|
|
|
ebecab |
@@ -1631,6 +1652,7 @@ execpline(Estate state, wordcode slcode, int how, int last1)
|
|
|
ebecab |
break;
|
|
|
ebecab |
}
|
|
|
ebecab |
child_unblock();
|
|
|
ebecab |
+ unqueue_signals();
|
|
|
ebecab |
|
|
|
ebecab |
if (list_pipe && (lastval & 0200) && pj >= 0 &&
|
|
|
ebecab |
(!(jn->stat & STAT_INUSE) || (jn->stat & STAT_DONE))) {
|
|
|
ebecab |
@@ -3192,6 +3214,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
|
|
ebecab |
fflush(xtrerr);
|
|
|
ebecab |
}
|
|
|
ebecab |
} else if (isset(EXECOPT) && !errflag) {
|
|
|
ebecab |
+ int q = queue_signal_level();
|
|
|
ebecab |
/*
|
|
|
ebecab |
* We delay the entersubsh() to here when we are exec'ing
|
|
|
ebecab |
* the current shell (including a fake exec to run a builtin then
|
|
|
ebecab |
@@ -3210,7 +3233,9 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
|
|
ebecab |
if (type >= WC_CURSH) {
|
|
|
ebecab |
if (last1 == 1)
|
|
|
ebecab |
do_exec = 1;
|
|
|
ebecab |
+ dont_queue_signals();
|
|
|
ebecab |
lastval = (execfuncs[type - WC_CURSH])(state, do_exec);
|
|
|
ebecab |
+ restore_queue_signals(q);
|
|
|
ebecab |
} else if (is_builtin || is_shfunc) {
|
|
|
ebecab |
LinkList restorelist = 0, removelist = 0;
|
|
|
ebecab |
/* builtin or shell function */
|
|
|
ebecab |
@@ -3269,7 +3294,9 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
|
|
ebecab |
/* It's a builtin */
|
|
|
ebecab |
if (forked)
|
|
|
ebecab |
closem(FDT_INTERNAL);
|
|
|
ebecab |
+ dont_queue_signals();
|
|
|
ebecab |
lastval = execbuiltin(args, (Builtin) hn);
|
|
|
ebecab |
+ restore_queue_signals(q);
|
|
|
ebecab |
#ifdef PATH_DEV_FD
|
|
|
ebecab |
closem(FDT_PROC_SUBST);
|
|
|
ebecab |
#endif
|
|
|
ebecab |
@@ -4415,11 +4442,9 @@ execshfunc(Shfunc shf, LinkList args)
|
|
|
ebecab |
if ((osfc = sfcontext) == SFC_NONE)
|
|
|
ebecab |
sfcontext = SFC_DIRECT;
|
|
|
ebecab |
xtrerr = stderr;
|
|
|
ebecab |
- unqueue_signals();
|
|
|
ebecab |
|
|
|
ebecab |
doshfunc(shf, args, 0);
|
|
|
ebecab |
|
|
|
ebecab |
- queue_signals();
|
|
|
ebecab |
sfcontext = osfc;
|
|
|
ebecab |
free(cmdstack);
|
|
|
ebecab |
cmdstack = ocs;
|
|
|
ebecab |
@@ -4614,6 +4639,8 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
|
|
|
ebecab |
static int funcdepth;
|
|
|
ebecab |
#endif
|
|
|
ebecab |
|
|
|
ebecab |
+ queue_signals(); /* Lots of memory and global state changes coming */
|
|
|
ebecab |
+
|
|
|
ebecab |
pushheap();
|
|
|
ebecab |
|
|
|
ebecab |
oargv0 = NULL;
|
|
|
ebecab |
@@ -4814,6 +4841,8 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
|
|
|
ebecab |
}
|
|
|
ebecab |
popheap();
|
|
|
ebecab |
|
|
|
ebecab |
+ unqueue_signals();
|
|
|
ebecab |
+
|
|
|
ebecab |
if (exit_pending) {
|
|
|
ebecab |
if (locallevel > forklevel) {
|
|
|
ebecab |
/* Still functions to return: force them to do so. */
|
|
|
ebecab |
@@ -4844,6 +4873,8 @@ runshfunc(Eprog prog, FuncWrap wrap, char *name)
|
|
|
ebecab |
int cont, ouu;
|
|
|
ebecab |
char *ou;
|
|
|
ebecab |
|
|
|
ebecab |
+ queue_signals();
|
|
|
ebecab |
+
|
|
|
ebecab |
ou = zalloc(ouu = underscoreused);
|
|
|
ebecab |
if (ou)
|
|
|
ebecab |
memcpy(ou, zunderscore, underscoreused);
|
|
|
ebecab |
@@ -4865,12 +4896,14 @@ runshfunc(Eprog prog, FuncWrap wrap, char *name)
|
|
|
ebecab |
wrap = wrap->next;
|
|
|
ebecab |
}
|
|
|
ebecab |
startparamscope();
|
|
|
ebecab |
- execode(prog, 1, 0, "shfunc");
|
|
|
ebecab |
+ execode(prog, 1, 0, "shfunc"); /* handles signal unqueueing */
|
|
|
ebecab |
if (ou) {
|
|
|
ebecab |
setunderscore(ou);
|
|
|
ebecab |
zfree(ou, ouu);
|
|
|
ebecab |
}
|
|
|
ebecab |
endparamscope();
|
|
|
ebecab |
+
|
|
|
ebecab |
+ unqueue_signals();
|
|
|
ebecab |
}
|
|
|
ebecab |
|
|
|
ebecab |
/* Search fpath for an undefined function. Finds the file, and returns the *
|
|
|
ebecab |
diff --git a/Src/init.c b/Src/init.c
|
|
|
ebecab |
index 78f171d..df42349 100644
|
|
|
ebecab |
--- a/Src/init.c
|
|
|
ebecab |
+++ b/Src/init.c
|
|
|
ebecab |
@@ -105,6 +105,7 @@ loop(int toplevel, int justonce)
|
|
|
ebecab |
Eprog prog;
|
|
|
ebecab |
int err, non_empty = 0;
|
|
|
ebecab |
|
|
|
ebecab |
+ queue_signals();
|
|
|
ebecab |
pushheap();
|
|
|
ebecab |
if (!toplevel)
|
|
|
ebecab |
lexsave();
|
|
|
ebecab |
@@ -118,7 +119,9 @@ loop(int toplevel, int justonce)
|
|
|
ebecab |
if (interact && toplevel) {
|
|
|
ebecab |
int hstop = stophist;
|
|
|
ebecab |
stophist = 3;
|
|
|
ebecab |
+ unqueue_signals();
|
|
|
ebecab |
preprompt();
|
|
|
ebecab |
+ queue_signals();
|
|
|
ebecab |
if (stophist != 3)
|
|
|
ebecab |
hbegin(1);
|
|
|
ebecab |
else
|
|
|
ebecab |
@@ -197,6 +200,7 @@ loop(int toplevel, int justonce)
|
|
|
ebecab |
if (((!interact || sourcelevel) && errflag) || retflag)
|
|
|
ebecab |
break;
|
|
|
ebecab |
if (isset(SINGLECOMMAND) && toplevel) {
|
|
|
ebecab |
+ dont_queue_signals();
|
|
|
ebecab |
if (sigtrapped[SIGEXIT])
|
|
|
ebecab |
dotrap(SIGEXIT);
|
|
|
ebecab |
exit(lastval);
|
|
|
ebecab |
@@ -208,6 +212,7 @@ loop(int toplevel, int justonce)
|
|
|
ebecab |
if (!toplevel)
|
|
|
ebecab |
lexrestore();
|
|
|
ebecab |
popheap();
|
|
|
ebecab |
+ unqueue_signals();
|
|
|
ebecab |
|
|
|
ebecab |
if (err)
|
|
|
ebecab |
return LOOP_ERROR;
|
|
|
ebecab |
diff --git a/Src/input.c b/Src/input.c
|
|
|
ebecab |
index 5b782dc..dcff78a 100644
|
|
|
ebecab |
--- a/Src/input.c
|
|
|
ebecab |
+++ b/Src/input.c
|
|
|
ebecab |
@@ -140,14 +140,17 @@ shingetline(void)
|
|
|
ebecab |
int c;
|
|
|
ebecab |
char buf[BUFSIZ];
|
|
|
ebecab |
char *p;
|
|
|
ebecab |
+ int q = queue_signal_level();
|
|
|
ebecab |
|
|
|
ebecab |
p = buf;
|
|
|
ebecab |
for (;;) {
|
|
|
ebecab |
+ dont_queue_signals();
|
|
|
ebecab |
do {
|
|
|
ebecab |
errno = 0;
|
|
|
ebecab |
c = fgetc(bshin);
|
|
|
ebecab |
} while (c < 0 && errno == EINTR);
|
|
|
ebecab |
if (c < 0 || c == '\n') {
|
|
|
ebecab |
+ restore_queue_signals(q);
|
|
|
ebecab |
if (c == '\n')
|
|
|
ebecab |
*p++ = '\n';
|
|
|
ebecab |
if (p > buf) {
|
|
|
ebecab |
@@ -163,11 +166,13 @@ shingetline(void)
|
|
|
ebecab |
} else
|
|
|
ebecab |
*p++ = c;
|
|
|
ebecab |
if (p >= buf + BUFSIZ - 1) {
|
|
|
ebecab |
+ queue_signals();
|
|
|
ebecab |
line = zrealloc(line, ll + (p - buf) + 1);
|
|
|
ebecab |
memcpy(line + ll, buf, p - buf);
|
|
|
ebecab |
ll += p - buf;
|
|
|
ebecab |
line[ll] = '\0';
|
|
|
ebecab |
p = buf;
|
|
|
ebecab |
+ unqueue_signals();
|
|
|
ebecab |
}
|
|
|
ebecab |
}
|
|
|
ebecab |
}
|
|
|
ebecab |
@@ -340,6 +345,8 @@ inputline(void)
|
|
|
ebecab |
static void
|
|
|
ebecab |
inputsetline(char *str, int flags)
|
|
|
ebecab |
{
|
|
|
ebecab |
+ queue_signals();
|
|
|
ebecab |
+
|
|
|
ebecab |
if ((inbufflags & INP_FREE) && inbuf) {
|
|
|
ebecab |
free(inbuf);
|
|
|
ebecab |
}
|
|
|
ebecab |
@@ -357,6 +364,8 @@ inputsetline(char *str, int flags)
|
|
|
ebecab |
else
|
|
|
ebecab |
inbufct = inbufleft;
|
|
|
ebecab |
inbufflags = flags;
|
|
|
ebecab |
+
|
|
|
ebecab |
+ unqueue_signals();
|
|
|
ebecab |
}
|
|
|
ebecab |
|
|
|
ebecab |
/*
|
|
|
ebecab |
diff --git a/Src/loop.c b/Src/loop.c
|
|
|
ebecab |
index 90a0761..0c07c73 100644
|
|
|
ebecab |
--- a/Src/loop.c
|
|
|
ebecab |
+++ b/Src/loop.c
|
|
|
ebecab |
@@ -56,6 +56,10 @@ execfor(Estate state, int do_exec)
|
|
|
ebecab |
char *name, *str, *cond = NULL, *advance = NULL;
|
|
|
ebecab |
zlong val = 0;
|
|
|
ebecab |
LinkList vars = NULL, args = NULL;
|
|
|
ebecab |
+ int old_simple_pline = simple_pline;
|
|
|
ebecab |
+
|
|
|
ebecab |
+ /* See comments in execwhile() */
|
|
|
ebecab |
+ simple_pline = 1;
|
|
|
ebecab |
|
|
|
ebecab |
end = state->pc + WC_FOR_SKIP(code);
|
|
|
ebecab |
|
|
|
ebecab |
@@ -73,6 +77,7 @@ execfor(Estate state, int do_exec)
|
|
|
ebecab |
matheval(str);
|
|
|
ebecab |
if (errflag) {
|
|
|
ebecab |
state->pc = end;
|
|
|
ebecab |
+ simple_pline = old_simple_pline;
|
|
|
ebecab |
return lastval = errflag;
|
|
|
ebecab |
}
|
|
|
ebecab |
cond = ecgetstr(state, EC_NODUP, &ctok);
|
|
|
ebecab |
@@ -85,6 +90,7 @@ execfor(Estate state, int do_exec)
|
|
|
ebecab |
|
|
|
ebecab |
if (!(args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok))) {
|
|
|
ebecab |
state->pc = end;
|
|
|
ebecab |
+ simple_pline = old_simple_pline;
|
|
|
ebecab |
return 0;
|
|
|
ebecab |
}
|
|
|
ebecab |
if (htok)
|
|
|
ebecab |
@@ -190,6 +196,7 @@ execfor(Estate state, int do_exec)
|
|
|
ebecab |
popheap();
|
|
|
ebecab |
cmdpop();
|
|
|
ebecab |
loops--;
|
|
|
ebecab |
+ simple_pline = old_simple_pline;
|
|
|
ebecab |
state->pc = end;
|
|
|
ebecab |
return lastval;
|
|
|
ebecab |
}
|
|
|
ebecab |
@@ -206,6 +213,10 @@ execselect(Estate state, UNUSED(int do_exec))
|
|
|
ebecab |
FILE *inp;
|
|
|
ebecab |
size_t more;
|
|
|
ebecab |
LinkList args;
|
|
|
ebecab |
+ int old_simple_pline = simple_pline;
|
|
|
ebecab |
+
|
|
|
ebecab |
+ /* See comments in execwhile() */
|
|
|
ebecab |
+ simple_pline = 1;
|
|
|
ebecab |
|
|
|
ebecab |
end = state->pc + WC_FOR_SKIP(code);
|
|
|
ebecab |
name = ecgetstr(state, EC_NODUP, NULL);
|
|
|
ebecab |
@@ -221,6 +232,7 @@ execselect(Estate state, UNUSED(int do_exec))
|
|
|
ebecab |
|
|
|
ebecab |
if (!(args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok))) {
|
|
|
ebecab |
state->pc = end;
|
|
|
ebecab |
+ simple_pline = old_simple_pline;
|
|
|
ebecab |
return 0;
|
|
|
ebecab |
}
|
|
|
ebecab |
if (htok)
|
|
|
ebecab |
@@ -228,6 +240,7 @@ execselect(Estate state, UNUSED(int do_exec))
|
|
|
ebecab |
}
|
|
|
ebecab |
if (!args || empty(args)) {
|
|
|
ebecab |
state->pc = end;
|
|
|
ebecab |
+ simple_pline = old_simple_pline;
|
|
|
ebecab |
return 1;
|
|
|
ebecab |
}
|
|
|
ebecab |
loops++;
|
|
|
ebecab |
@@ -301,6 +314,7 @@ execselect(Estate state, UNUSED(int do_exec))
|
|
|
ebecab |
popheap();
|
|
|
ebecab |
fclose(inp);
|
|
|
ebecab |
loops--;
|
|
|
ebecab |
+ simple_pline = old_simple_pline;
|
|
|
ebecab |
state->pc = end;
|
|
|
ebecab |
return lastval;
|
|
|
ebecab |
}
|
|
|
ebecab |
@@ -368,6 +382,7 @@ execwhile(Estate state, UNUSED(int do_exec))
|
|
|
ebecab |
Wordcode end, loop;
|
|
|
ebecab |
wordcode code = state->pc[-1];
|
|
|
ebecab |
int olderrexit, oldval, isuntil = (WC_WHILE_TYPE(code) == WC_WHILE_UNTIL);
|
|
|
ebecab |
+ int old_simple_pline = simple_pline;
|
|
|
ebecab |
|
|
|
ebecab |
end = state->pc + WC_WHILE_SKIP(code);
|
|
|
ebecab |
olderrexit = noerrexit;
|
|
|
ebecab |
@@ -382,8 +397,6 @@ execwhile(Estate state, UNUSED(int do_exec))
|
|
|
ebecab |
/* This is an empty loop. Make sure the signal handler sets the
|
|
|
ebecab |
* flags and then just wait for someone hitting ^C. */
|
|
|
ebecab |
|
|
|
ebecab |
- int old_simple_pline = simple_pline;
|
|
|
ebecab |
-
|
|
|
ebecab |
simple_pline = 1;
|
|
|
ebecab |
|
|
|
ebecab |
while (!breaks)
|
|
|
ebecab |
@@ -395,7 +408,14 @@ execwhile(Estate state, UNUSED(int do_exec))
|
|
|
ebecab |
for (;;) {
|
|
|
ebecab |
state->pc = loop;
|
|
|
ebecab |
noerrexit = 1;
|
|
|
ebecab |
+
|
|
|
ebecab |
+ /* In case the test condition is a functional no-op,
|
|
|
ebecab |
+ * make sure signal handlers recognize ^C to end the loop. */
|
|
|
ebecab |
+ simple_pline = 1;
|
|
|
ebecab |
+
|
|
|
ebecab |
execlist(state, 1, 0);
|
|
|
ebecab |
+
|
|
|
ebecab |
+ simple_pline = old_simple_pline;
|
|
|
ebecab |
noerrexit = olderrexit;
|
|
|
ebecab |
if (!((lastval == 0) ^ isuntil)) {
|
|
|
ebecab |
if (breaks)
|
|
|
ebecab |
@@ -407,7 +427,14 @@ execwhile(Estate state, UNUSED(int do_exec))
|
|
|
ebecab |
lastval = oldval;
|
|
|
ebecab |
break;
|
|
|
ebecab |
}
|
|
|
ebecab |
+
|
|
|
ebecab |
+ /* In case the loop body is also a functional no-op,
|
|
|
ebecab |
+ * make sure signal handlers recognize ^C as above. */
|
|
|
ebecab |
+ simple_pline = 1;
|
|
|
ebecab |
+
|
|
|
ebecab |
execlist(state, 1, 0);
|
|
|
ebecab |
+
|
|
|
ebecab |
+ simple_pline = old_simple_pline;
|
|
|
ebecab |
if (breaks) {
|
|
|
ebecab |
breaks--;
|
|
|
ebecab |
if (breaks || !contflag)
|
|
|
ebecab |
@@ -438,6 +465,10 @@ execrepeat(Estate state, UNUSED(int do_exec))
|
|
|
ebecab |
wordcode code = state->pc[-1];
|
|
|
ebecab |
int count, htok = 0;
|
|
|
ebecab |
char *tmp;
|
|
|
ebecab |
+ int old_simple_pline = simple_pline;
|
|
|
ebecab |
+
|
|
|
ebecab |
+ /* See comments in execwhile() */
|
|
|
ebecab |
+ simple_pline = 1;
|
|
|
ebecab |
|
|
|
ebecab |
end = state->pc + WC_REPEAT_SKIP(code);
|
|
|
ebecab |
|
|
|
ebecab |
@@ -470,6 +501,7 @@ execrepeat(Estate state, UNUSED(int do_exec))
|
|
|
ebecab |
cmdpop();
|
|
|
ebecab |
popheap();
|
|
|
ebecab |
loops--;
|
|
|
ebecab |
+ simple_pline = old_simple_pline;
|
|
|
ebecab |
state->pc = end;
|
|
|
ebecab |
return lastval;
|
|
|
ebecab |
}
|
|
|
ebecab |
diff --git a/Src/parse.c b/Src/parse.c
|
|
|
ebecab |
index b0a7624..04d2707 100644
|
|
|
ebecab |
--- a/Src/parse.c
|
|
|
ebecab |
+++ b/Src/parse.c
|
|
|
ebecab |
@@ -379,6 +379,8 @@ init_parse_status(void)
|
|
|
ebecab |
void
|
|
|
ebecab |
init_parse(void)
|
|
|
ebecab |
{
|
|
|
ebecab |
+ queue_signals();
|
|
|
ebecab |
+
|
|
|
ebecab |
if (ecbuf) zfree(ecbuf, eclen);
|
|
|
ebecab |
|
|
|
ebecab |
ecbuf = (Wordcode) zalloc((eclen = EC_INIT_SIZE) * sizeof(wordcode));
|
|
|
ebecab |
@@ -389,6 +391,8 @@ init_parse(void)
|
|
|
ebecab |
ecnfunc = 0;
|
|
|
ebecab |
|
|
|
ebecab |
init_parse_status();
|
|
|
ebecab |
+
|
|
|
ebecab |
+ unqueue_signals();
|
|
|
ebecab |
}
|
|
|
ebecab |
|
|
|
ebecab |
/* Build eprog. */
|
|
|
ebecab |
@@ -409,6 +413,8 @@ bld_eprog(void)
|
|
|
ebecab |
Eprog ret;
|
|
|
ebecab |
int l;
|
|
|
ebecab |
|
|
|
ebecab |
+ queue_signals();
|
|
|
ebecab |
+
|
|
|
ebecab |
ecadd(WCB_END());
|
|
|
ebecab |
|
|
|
ebecab |
ret = (Eprog) zhalloc(sizeof(*ret));
|
|
|
ebecab |
@@ -431,6 +437,8 @@ bld_eprog(void)
|
|
|
ebecab |
zfree(ecbuf, eclen);
|
|
|
ebecab |
ecbuf = NULL;
|
|
|
ebecab |
|
|
|
ebecab |
+ unqueue_signals();
|
|
|
ebecab |
+
|
|
|
ebecab |
return ret;
|
|
|
ebecab |
}
|
|
|
ebecab |
|
|
|
ebecab |
diff --git a/Src/signals.c b/Src/signals.c
|
|
|
ebecab |
index c539063..73b41b1 100644
|
|
|
ebecab |
--- a/Src/signals.c
|
|
|
ebecab |
+++ b/Src/signals.c
|
|
|
ebecab |
@@ -1194,6 +1194,8 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
|
|
|
ebecab |
}
|
|
|
ebecab |
}
|
|
|
ebecab |
|
|
|
ebecab |
+ queue_signals(); /* Any time we manage memory or global state */
|
|
|
ebecab |
+
|
|
|
ebecab |
intrap++;
|
|
|
ebecab |
*sigtr |= ZSIG_IGNORED;
|
|
|
ebecab |
|
|
|
ebecab |
@@ -1231,7 +1233,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
|
|
|
ebecab |
|
|
|
ebecab |
sfcontext = SFC_SIGNAL;
|
|
|
ebecab |
incompfunc = 0;
|
|
|
ebecab |
- doshfunc((Shfunc)sigfn, args, 1);
|
|
|
ebecab |
+ doshfunc((Shfunc)sigfn, args, 1); /* manages signal queueing */
|
|
|
ebecab |
sfcontext = osc;
|
|
|
ebecab |
incompfunc= old_incompfunc;
|
|
|
ebecab |
freelinklist(args, (FreeFunc) NULL);
|
|
|
ebecab |
@@ -1241,7 +1243,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
|
|
|
ebecab |
trap_state = TRAP_STATE_PRIMED;
|
|
|
ebecab |
trapisfunc = isfunc = 0;
|
|
|
ebecab |
|
|
|
ebecab |
- execode((Eprog)sigfn, 1, 0, "trap");
|
|
|
ebecab |
+ execode((Eprog)sigfn, 1, 0, "trap"); /* manages signal queueing */
|
|
|
ebecab |
}
|
|
|
ebecab |
runhookdef(AFTERTRAPHOOK, NULL);
|
|
|
ebecab |
|
|
|
ebecab |
@@ -1286,6 +1288,8 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
|
|
|
ebecab |
if (*sigtr != ZSIG_IGNORED)
|
|
|
ebecab |
*sigtr &= ~ZSIG_IGNORED;
|
|
|
ebecab |
intrap--;
|
|
|
ebecab |
+
|
|
|
ebecab |
+ unqueue_signals();
|
|
|
ebecab |
}
|
|
|
ebecab |
|
|
|
ebecab |
/* Standard call to execute a trap for a given signal. */
|
|
|
ebecab |
--
|
|
|
ebecab |
2.5.0
|
|
|
ebecab |
|
|
|
ebecab |
|
|
|
ebecab |
From 33905958a1b94e83ca1c32bc6849906da94b91a6 Mon Sep 17 00:00:00 2001
|
|
|
ebecab |
From: "Barton E. Schaefer" <schaefer@zsh.org>
|
|
|
ebecab |
Date: Sun, 9 Aug 2015 17:37:23 -0700
|
|
|
ebecab |
Subject: [PATCH 3/8] 36033: a few more queue_signals() to protect global state
|
|
|
ebecab |
changes
|
|
|
ebecab |
|
|
|
ebecab |
Upstream-commit: df5f825538720a9422859200d58d075d1dd075fc
|
|
|
ebecab |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
ebecab |
---
|
|
|
ebecab |
Src/glob.c | 4 ++++
|
|
|
ebecab |
Src/pattern.c | 8 +++++++-
|
|
|
ebecab |
2 files changed, 11 insertions(+), 1 deletion(-)
|
|
|
ebecab |
|
|
|
ebecab |
diff --git a/Src/glob.c b/Src/glob.c
|
|
|
ebecab |
index ca2ffaf..9135fce 100644
|
|
|
ebecab |
--- a/Src/glob.c
|
|
|
ebecab |
+++ b/Src/glob.c
|
|
|
ebecab |
@@ -213,22 +213,26 @@ static struct globdata curglobdata;
|
|
|
ebecab |
|
|
|
ebecab |
#define save_globstate(N) \
|
|
|
ebecab |
do { \
|
|
|
ebecab |
+ queue_signals(); \
|
|
|
ebecab |
memcpy(&(N), &curglobdata, sizeof(struct globdata)); \
|
|
|
ebecab |
(N).gd_pathpos = pathpos; \
|
|
|
ebecab |
(N).gd_pathbuf = pathbuf; \
|
|
|
ebecab |
(N).gd_glob_pre = glob_pre; \
|
|
|
ebecab |
(N).gd_glob_suf = glob_suf; \
|
|
|
ebecab |
pathbuf = NULL; \
|
|
|
ebecab |
+ unqueue_signals(); \
|
|
|
ebecab |
} while (0)
|
|
|
ebecab |
|
|
|
ebecab |
#define restore_globstate(N) \
|
|
|
ebecab |
do { \
|
|
|
ebecab |
+ queue_signals(); \
|
|
|
ebecab |
zfree(pathbuf, pathbufsz); \
|
|
|
ebecab |
memcpy(&curglobdata, &(N), sizeof(struct globdata)); \
|
|
|
ebecab |
pathpos = (N).gd_pathpos; \
|
|
|
ebecab |
pathbuf = (N).gd_pathbuf; \
|
|
|
ebecab |
glob_pre = (N).gd_glob_pre; \
|
|
|
ebecab |
glob_suf = (N).gd_glob_suf; \
|
|
|
ebecab |
+ unqueue_signals(); \
|
|
|
ebecab |
} while (0)
|
|
|
ebecab |
|
|
|
ebecab |
/* pathname component in filename patterns */
|
|
|
ebecab |
diff --git a/Src/pattern.c b/Src/pattern.c
|
|
|
ebecab |
index b74a08a..52774c0 100644
|
|
|
ebecab |
--- a/Src/pattern.c
|
|
|
ebecab |
+++ b/Src/pattern.c
|
|
|
ebecab |
@@ -452,6 +452,8 @@ patcompile(char *exp, int inflags, char **endexp)
|
|
|
ebecab |
char *lng, *strp = NULL;
|
|
|
ebecab |
Patprog p;
|
|
|
ebecab |
|
|
|
ebecab |
+ queue_signals();
|
|
|
ebecab |
+
|
|
|
ebecab |
startoff = sizeof(struct patprog);
|
|
|
ebecab |
/* Ensure alignment of start of program string */
|
|
|
ebecab |
startoff = (startoff + sizeof(union upat) - 1) & ~(sizeof(union upat) - 1);
|
|
|
ebecab |
@@ -521,8 +523,10 @@ patcompile(char *exp, int inflags, char **endexp)
|
|
|
ebecab |
if (!strp || (*strp && *strp != '/')) {
|
|
|
ebecab |
/* No, do normal compilation. */
|
|
|
ebecab |
strp = NULL;
|
|
|
ebecab |
- if (patcompswitch(0, &flags) == 0)
|
|
|
ebecab |
+ if (patcompswitch(0, &flags) == 0) {
|
|
|
ebecab |
+ unqueue_signals();
|
|
|
ebecab |
return NULL;
|
|
|
ebecab |
+ }
|
|
|
ebecab |
} else {
|
|
|
ebecab |
/*
|
|
|
ebecab |
* Yes, copy the string, and skip compilation altogether.
|
|
|
ebecab |
@@ -654,6 +658,8 @@ patcompile(char *exp, int inflags, char **endexp)
|
|
|
ebecab |
|
|
|
ebecab |
if (endexp)
|
|
|
ebecab |
*endexp = patparse;
|
|
|
ebecab |
+
|
|
|
ebecab |
+ unqueue_signals();
|
|
|
ebecab |
return p;
|
|
|
ebecab |
}
|
|
|
ebecab |
|
|
|
ebecab |
--
|
|
|
ebecab |
2.5.0
|
|
|
ebecab |
|
|
|
ebecab |
|
|
|
ebecab |
From bba38460c88c36fb529ee7494570cb2cfc68641a Mon Sep 17 00:00:00 2001
|
|
|
ebecab |
From: Peter Stephenson <pws@zsh.org>
|
|
|
ebecab |
Date: Mon, 10 Aug 2015 16:59:55 +0100
|
|
|
ebecab |
Subject: [PATCH 4/8] Don't rely on implicit value when saving background
|
|
|
ebecab |
process status
|
|
|
ebecab |
|
|
|
ebecab |
Upstream-commit: a07f74fadd1180b42258d1fcec5359afe3f9ba00
|
|
|
ebecab |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
ebecab |
---
|
|
|
ebecab |
Src/signals.c | 9 ++++++++-
|
|
|
ebecab |
1 file changed, 8 insertions(+), 1 deletion(-)
|
|
|
ebecab |
|
|
|
ebecab |
diff --git a/Src/signals.c b/Src/signals.c
|
|
|
ebecab |
index 73b41b1..2e7304f 100644
|
|
|
ebecab |
--- a/Src/signals.c
|
|
|
ebecab |
+++ b/Src/signals.c
|
|
|
ebecab |
@@ -533,7 +533,14 @@ wait_for_processes(void)
|
|
|
ebecab |
*/
|
|
|
ebecab |
if (jn && !(jn->stat & (STAT_CURSH|STAT_BUILTIN)) &&
|
|
|
ebecab |
jn - jobtab != thisjob)
|
|
|
ebecab |
- addbgstatus(pid, (int)lastval2);
|
|
|
ebecab |
+ {
|
|
|
ebecab |
+ int val = (WIFSIGNALED(status) ?
|
|
|
ebecab |
+ 0200 | WTERMSIG(status) :
|
|
|
ebecab |
+ (WIFSTOPPED(status) ?
|
|
|
ebecab |
+ 0200 | WEXITSTATUS(status) :
|
|
|
ebecab |
+ WEXITSTATUS(status)));
|
|
|
ebecab |
+ addbgstatus(pid, val);
|
|
|
ebecab |
+ }
|
|
|
ebecab |
|
|
|
ebecab |
unqueue_signals();
|
|
|
ebecab |
}
|
|
|
ebecab |
--
|
|
|
ebecab |
2.5.0
|
|
|
ebecab |
|
|
|
ebecab |
|
|
|
ebecab |
From 530b59d58273c9f11cd1443c0865f6420eafcbf0 Mon Sep 17 00:00:00 2001
|
|
|
ebecab |
From: "Barton E. Schaefer" <schaefer@zsh.org>
|
|
|
ebecab |
Date: Tue, 11 Aug 2015 08:44:15 -0700
|
|
|
ebecab |
Subject: [PATCH 5/8] 36090: keep signals queued for preprompt()
|
|
|
ebecab |
|
|
|
ebecab |
Upstream-commit: 1af2e6e02d5cb8ca8d11f107b670cddfd10a7e81
|
|
|
ebecab |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
ebecab |
---
|
|
|
ebecab |
Src/init.c | 2 --
|
|
|
ebecab |
1 file changed, 2 deletions(-)
|
|
|
ebecab |
|
|
|
ebecab |
diff --git a/Src/init.c b/Src/init.c
|
|
|
ebecab |
index df42349..ca616d3 100644
|
|
|
ebecab |
--- a/Src/init.c
|
|
|
ebecab |
+++ b/Src/init.c
|
|
|
ebecab |
@@ -119,9 +119,7 @@ loop(int toplevel, int justonce)
|
|
|
ebecab |
if (interact && toplevel) {
|
|
|
ebecab |
int hstop = stophist;
|
|
|
ebecab |
stophist = 3;
|
|
|
ebecab |
- unqueue_signals();
|
|
|
ebecab |
preprompt();
|
|
|
ebecab |
- queue_signals();
|
|
|
ebecab |
if (stophist != 3)
|
|
|
ebecab |
hbegin(1);
|
|
|
ebecab |
else
|
|
|
ebecab |
--
|
|
|
ebecab |
2.5.0
|
|
|
ebecab |
|
|
|
ebecab |
|
|
|
ebecab |
From b2994c9f3ef36c3ee3286a08736da1e2c8d65f0b Mon Sep 17 00:00:00 2001
|
|
|
ebecab |
From: "Barton E. Schaefer" <schaefer@zsh.org>
|
|
|
ebecab |
Date: Tue, 11 Aug 2015 08:53:12 -0700
|
|
|
ebecab |
Subject: [PATCH 6/8] 36104: change order of child_block() and
|
|
|
ebecab |
dont_queue_signals() to resolve yet another race condition
|
|
|
ebecab |
|
|
|
ebecab |
Upstream-commit: 128bf385b1e8256e412d732fa9b80ecd7c5e2c73
|
|
|
ebecab |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
ebecab |
---
|
|
|
ebecab |
Src/exec.c | 2 +-
|
|
|
ebecab |
Src/jobs.c | 4 ++--
|
|
|
ebecab |
2 files changed, 3 insertions(+), 3 deletions(-)
|
|
|
ebecab |
|
|
|
ebecab |
diff --git a/Src/exec.c b/Src/exec.c
|
|
|
ebecab |
index cff1a24..70e2279 100644
|
|
|
ebecab |
--- a/Src/exec.c
|
|
|
ebecab |
+++ b/Src/exec.c
|
|
|
ebecab |
@@ -1570,8 +1570,8 @@ execpline(Estate state, wordcode slcode, int how, int last1)
|
|
|
ebecab |
!(jobtab[list_pipe_job].stat & STAT_STOPPED)) {
|
|
|
ebecab |
int q = queue_signal_level();
|
|
|
ebecab |
child_unblock();
|
|
|
ebecab |
- dont_queue_signals();
|
|
|
ebecab |
child_block();
|
|
|
ebecab |
+ dont_queue_signals();
|
|
|
ebecab |
restore_queue_signals(q);
|
|
|
ebecab |
}
|
|
|
ebecab |
if (list_pipe_child &&
|
|
|
ebecab |
diff --git a/Src/jobs.c b/Src/jobs.c
|
|
|
ebecab |
index 24b8494..e711a9b 100644
|
|
|
ebecab |
--- a/Src/jobs.c
|
|
|
ebecab |
+++ b/Src/jobs.c
|
|
|
ebecab |
@@ -1312,9 +1312,9 @@ zwaitjob(int job, int wait_cmd)
|
|
|
ebecab |
int q = queue_signal_level();
|
|
|
ebecab |
Job jn = jobtab + job;
|
|
|
ebecab |
|
|
|
ebecab |
- dont_queue_signals();
|
|
|
ebecab |
child_block(); /* unblocked during signal_suspend() */
|
|
|
ebecab |
queue_traps(wait_cmd);
|
|
|
ebecab |
+ dont_queue_signals();
|
|
|
ebecab |
if (jn->procs || jn->auxprocs) { /* if any forks were done */
|
|
|
ebecab |
jn->stat |= STAT_LOCKED;
|
|
|
ebecab |
if (jn->stat & STAT_CHANGED)
|
|
|
ebecab |
@@ -1350,9 +1350,9 @@ zwaitjob(int job, int wait_cmd)
|
|
|
ebecab |
pipestats[0] = lastval;
|
|
|
ebecab |
numpipestats = 1;
|
|
|
ebecab |
}
|
|
|
ebecab |
+ restore_queue_signals(q);
|
|
|
ebecab |
unqueue_traps();
|
|
|
ebecab |
child_unblock();
|
|
|
ebecab |
- restore_queue_signals(q);
|
|
|
ebecab |
|
|
|
ebecab |
return 0;
|
|
|
ebecab |
}
|
|
|
ebecab |
--
|
|
|
ebecab |
2.5.0
|
|
|
ebecab |
|
|
|
ebecab |
|
|
|
ebecab |
From 6a0fd02f08972875cc138e783e28515a5c7a7e04 Mon Sep 17 00:00:00 2001
|
|
|
ebecab |
From: "Barton E. Schaefer" <schaefer@zsh.org>
|
|
|
ebecab |
Date: Sat, 15 Aug 2015 10:15:30 -0700
|
|
|
ebecab |
Subject: [PATCH 7/8] 36180: avoid infinite job stop/continue loop on "wait
|
|
|
ebecab |
PID" for a background job
|
|
|
ebecab |
|
|
|
ebecab |
Upstream-commit: 5d019f426af8b2a600ee03e43782c24b357d1401
|
|
|
ebecab |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
ebecab |
---
|
|
|
ebecab |
Src/jobs.c | 9 ++++++++-
|
|
|
ebecab |
1 file changed, 8 insertions(+), 1 deletion(-)
|
|
|
ebecab |
|
|
|
ebecab |
diff --git a/Src/jobs.c b/Src/jobs.c
|
|
|
ebecab |
index e711a9b..9b94a1f 100644
|
|
|
ebecab |
--- a/Src/jobs.c
|
|
|
ebecab |
+++ b/Src/jobs.c
|
|
|
ebecab |
@@ -1276,10 +1276,17 @@ waitforpid(pid_t pid, int wait_cmd)
|
|
|
ebecab |
dont_queue_signals();
|
|
|
ebecab |
child_block(); /* unblocked in signal_suspend() */
|
|
|
ebecab |
queue_traps(wait_cmd);
|
|
|
ebecab |
+
|
|
|
ebecab |
+ /* This function should never be called with a pid that is not a
|
|
|
ebecab |
+ * child of the current shell. Consequently, if kill(0, pid)
|
|
|
ebecab |
+ * fails here with ESRCH, the child has already been reaped. In
|
|
|
ebecab |
+ * the loop body, we expect this to happen in signal_suspend()
|
|
|
ebecab |
+ * via zhandler(), after which this test terminates the loop.
|
|
|
ebecab |
+ */
|
|
|
ebecab |
while (!errflag && (kill(pid, 0) >= 0 || errno != ESRCH)) {
|
|
|
ebecab |
if (first)
|
|
|
ebecab |
first = 0;
|
|
|
ebecab |
- else
|
|
|
ebecab |
+ else if (!wait_cmd)
|
|
|
ebecab |
kill(pid, SIGCONT);
|
|
|
ebecab |
|
|
|
ebecab |
last_signal = -1;
|
|
|
ebecab |
--
|
|
|
ebecab |
2.5.0
|
|
|
ebecab |
|
|
|
ebecab |
|
|
|
ebecab |
From d184dd8673c93d35855b4a04613ae09277214df5 Mon Sep 17 00:00:00 2001
|
|
|
ebecab |
From: "Barton E. Schaefer" <schaefer@zsh.org>
|
|
|
ebecab |
Date: Wed, 2 Sep 2015 19:11:54 -0700
|
|
|
ebecab |
Subject: [PATCH 8/8] 36393: process queued signals during dotrap()
|
|
|
ebecab |
|
|
|
ebecab |
Upstream-commit: 9f5dffa1f33ec43c306bdf3c87cebba5fcc95b64
|
|
|
ebecab |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
ebecab |
---
|
|
|
ebecab |
Src/signals.c | 5 +++++
|
|
|
ebecab |
Test/A05execution.ztst | 9 +++++++++
|
|
|
ebecab |
2 files changed, 14 insertions(+)
|
|
|
ebecab |
|
|
|
ebecab |
diff --git a/Src/signals.c b/Src/signals.c
|
|
|
ebecab |
index 2e7304f..dbc84af 100644
|
|
|
ebecab |
--- a/Src/signals.c
|
|
|
ebecab |
+++ b/Src/signals.c
|
|
|
ebecab |
@@ -1306,6 +1306,7 @@ void
|
|
|
ebecab |
dotrap(int sig)
|
|
|
ebecab |
{
|
|
|
ebecab |
void *funcprog;
|
|
|
ebecab |
+ int q = queue_signal_level();
|
|
|
ebecab |
|
|
|
ebecab |
if (sigtrapped[sig] & ZSIG_FUNC) {
|
|
|
ebecab |
HashNode hn = gettrapnode(sig, 0);
|
|
|
ebecab |
@@ -1328,5 +1329,9 @@ dotrap(int sig)
|
|
|
ebecab |
if ((sigtrapped[sig] & ZSIG_IGNORED) || !funcprog || errflag)
|
|
|
ebecab |
return;
|
|
|
ebecab |
|
|
|
ebecab |
+ dont_queue_signals();
|
|
|
ebecab |
+
|
|
|
ebecab |
dotrapargs(sig, sigtrapped+sig, funcprog);
|
|
|
ebecab |
+
|
|
|
ebecab |
+ restore_queue_signals(q);
|
|
|
ebecab |
}
|
|
|
ebecab |
diff --git a/Test/A05execution.ztst b/Test/A05execution.ztst
|
|
|
ebecab |
index 77c569c..3b39c75 100644
|
|
|
ebecab |
--- a/Test/A05execution.ztst
|
|
|
ebecab |
+++ b/Test/A05execution.ztst
|
|
|
ebecab |
@@ -203,3 +203,12 @@
|
|
|
ebecab |
1:The status of recently exited background jobs is recorded
|
|
|
ebecab |
>3
|
|
|
ebecab |
>2
|
|
|
ebecab |
+
|
|
|
ebecab |
+# Regression test for workers/36392
|
|
|
ebecab |
+ print -u $ZTST_fd 'This test takes 3 seconds and hangs the shell when it fails...'
|
|
|
ebecab |
+ callfromchld() { true && { print CHLD } }
|
|
|
ebecab |
+ TRAPCHLD() { callfromchld }
|
|
|
ebecab |
+ sleep 2 & sleep 3; print OK
|
|
|
ebecab |
+0:Background job exit does not affect reaping foreground job
|
|
|
ebecab |
+>CHLD
|
|
|
ebecab |
+>OK
|
|
|
ebecab |
--
|
|
|
ebecab |
2.5.0
|
|
|
ebecab |
|