diff options
author | Peter Stephenson <p.stephenson@samsung.com> | 2022-03-30 09:28:43 +0100 |
---|---|---|
committer | Peter Stephenson <p.stephenson@samsung.com> | 2022-03-30 09:28:43 +0100 |
commit | 98e46340867028808e71e7f3373881cb7e5b6764 (patch) | |
tree | ce804301a1890959e620dabf3e87da5a63503f80 /Src | |
parent | f11227f78d8d477048194df5b93dfe315d4b1588 (diff) | |
download | zsh-98e46340867028808e71e7f3373881cb7e5b6764.tar.gz zsh-98e46340867028808e71e7f3373881cb7e5b6764.tar.xz zsh-98e46340867028808e71e7f3373881cb7e5b6764.zip |
49906 (Bart), 49911: Fixes to querying jobs in subshell.
Don't attempt to query invalid job off end of table, resulting in crashes from $jobtstates. If background task started in subshell, look at tatsks within subshell instead of main shell. Document and add test.
Diffstat (limited to 'Src')
-rw-r--r-- | Src/exec.c | 1 | ||||
-rw-r--r-- | Src/jobs.c | 20 |
2 files changed, 21 insertions, 0 deletions
diff --git a/Src/exec.c b/Src/exec.c index 70cbfc97f..27d49e005 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1689,6 +1689,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) execpline2(state, code, how, opipe[0], ipipe[1], last1); pline_level--; if (how & Z_ASYNC) { + clearoldjobtab(); lastwj = newjob; if (thisjob == list_pipe_job) diff --git a/Src/jobs.c b/Src/jobs.c index 18e43f03c..af0a1233d 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -1718,8 +1718,15 @@ clearjobtab(int monitor) /* Don't report any job we're part of */ if (thisjob != -1 && thisjob < oldmaxjob) memset(oldjobtab+thisjob, 0, sizeof(struct job)); + + /* oldmaxjob is now the size of the table, but outside + * this function, it's used as a job number, which must + * be the largest index available in the table. + */ + --oldmaxjob; } + memset(jobtab, 0, jobtabsize * sizeof(struct job)); /* zero out table */ maxjob = 0; @@ -1733,6 +1740,18 @@ clearjobtab(int monitor) thisjob = initjob(); } +/* In a subshell, decide we want our own job table after all. */ + +/**/ +mod_export void +clearoldjobtab(void) +{ + if (oldjobtab) + free(oldjobtab); + oldjobtab = NULL; + oldmaxjob = 0; +} + static int initnewjob(int i) { jobtab[i].stat = STAT_INUSE; @@ -2449,6 +2468,7 @@ bin_fg(char *name, char **argv, Options ops, int func) case BIN_BG: case BIN_WAIT: if (func == BIN_BG) { + clearoldjobtab(); jobtab[job].stat |= STAT_NOSTTY; jobtab[job].stat &= ~STAT_CURSH; } |