mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-12-29 16:25:35 +01:00
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.
This commit is contained in:
parent
f11227f78d
commit
98e4634086
6 changed files with 81 additions and 0 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2022-03-30 Peter Stephenson <p.stephenson@samsung.com>
|
||||||
|
|
||||||
|
* 49906 (Bart), 49911: Doc/Zsh/builtins.yo,
|
||||||
|
Doc/Zsh/mod_parameter.yo, Src/exec.c, Src/jobs.c,
|
||||||
|
Test/W03jobparameters.ztst: Fix querying jobs in subshell.
|
||||||
|
Don't uery invalid job at end, if background job started in
|
||||||
|
subshell query jobs in subshell instead of main shell.
|
||||||
|
|
||||||
2022-03-30 Mikael Magnusson <mikachu@gmail.com>
|
2022-03-30 Mikael Magnusson <mikachu@gmail.com>
|
||||||
|
|
||||||
* 49893: Src/Zle/comp.h, Src/Zle/compcore.c: Fix comments for
|
* 49893: Src/Zle/comp.h, Src/Zle/compcore.c: Fix comments for
|
||||||
|
|
|
@ -1114,6 +1114,24 @@ The tt(-Z) option replaces the shell's argument and environment space with
|
||||||
the given string, truncated if necessary to fit. This will normally be
|
the given string, truncated if necessary to fit. This will normally be
|
||||||
visible in tt(ps) (manref(ps)(1)) listings. This feature is typically
|
visible in tt(ps) (manref(ps)(1)) listings. This feature is typically
|
||||||
used by daemons, to indicate their state.
|
used by daemons, to indicate their state.
|
||||||
|
|
||||||
|
Full job control is only available in the top-level interactive shell,
|
||||||
|
not in commands run in the left hand side of pipelines or within
|
||||||
|
the tt(LPAR())var(...)tt(RPAR()) construct. However, a snapshot
|
||||||
|
of the job state at that point is taken, so it is still possible
|
||||||
|
to use the tt(jobs) builtin, or any parameter providing job information.
|
||||||
|
This gives information about the state of jobs at the point the subshell
|
||||||
|
was created. If background processes are created within the subshell,
|
||||||
|
then instead information about those processes is provided.
|
||||||
|
|
||||||
|
For example,
|
||||||
|
|
||||||
|
example(sleep 10 & # Job in background
|
||||||
|
LPAR() # Shell forks
|
||||||
|
jobs # Shows information about "sleep 10 &"
|
||||||
|
sleep 5 & # Process in background (no job control)
|
||||||
|
jobs # Shows information about "sleep 5 &"
|
||||||
|
RPAR())
|
||||||
)
|
)
|
||||||
findex(kill)
|
findex(kill)
|
||||||
cindex(killing jobs)
|
cindex(killing jobs)
|
||||||
|
|
|
@ -165,6 +165,8 @@ The keys of the associative arrays are usually valid job numbers,
|
||||||
and these are the values output with, for example, tt(${(k)jobdirs}).
|
and these are the values output with, for example, tt(${(k)jobdirs}).
|
||||||
Non-numeric job references may be used when looking up a value;
|
Non-numeric job references may be used when looking up a value;
|
||||||
for example, tt(${jobdirs[%+]}) refers to the current job.
|
for example, tt(${jobdirs[%+]}) refers to the current job.
|
||||||
|
|
||||||
|
See the tt(jobs) builtin for how job information is provided in a subshell.
|
||||||
)
|
)
|
||||||
vindex(jobtexts)
|
vindex(jobtexts)
|
||||||
item(tt(jobtexts))(
|
item(tt(jobtexts))(
|
||||||
|
@ -173,6 +175,8 @@ that were used to start the jobs.
|
||||||
|
|
||||||
Handling of the keys of the associative array is as described for
|
Handling of the keys of the associative array is as described for
|
||||||
tt(jobdirs) above.
|
tt(jobdirs) above.
|
||||||
|
|
||||||
|
See the tt(jobs) builtin for how job information is provided in a subshell.
|
||||||
)
|
)
|
||||||
vindex(jobstates)
|
vindex(jobstates)
|
||||||
item(tt(jobstates))(
|
item(tt(jobstates))(
|
||||||
|
@ -189,6 +193,8 @@ the var(state) describes the state of that process.
|
||||||
|
|
||||||
Handling of the keys of the associative array is as described for
|
Handling of the keys of the associative array is as described for
|
||||||
tt(jobdirs) above.
|
tt(jobdirs) above.
|
||||||
|
|
||||||
|
See the tt(jobs) builtin for how job information is provided in a subshell.
|
||||||
)
|
)
|
||||||
vindex(nameddirs)
|
vindex(nameddirs)
|
||||||
item(tt(nameddirs))(
|
item(tt(nameddirs))(
|
||||||
|
|
|
@ -1689,6 +1689,7 @@ execpline(Estate state, wordcode slcode, int how, int last1)
|
||||||
execpline2(state, code, how, opipe[0], ipipe[1], last1);
|
execpline2(state, code, how, opipe[0], ipipe[1], last1);
|
||||||
pline_level--;
|
pline_level--;
|
||||||
if (how & Z_ASYNC) {
|
if (how & Z_ASYNC) {
|
||||||
|
clearoldjobtab();
|
||||||
lastwj = newjob;
|
lastwj = newjob;
|
||||||
|
|
||||||
if (thisjob == list_pipe_job)
|
if (thisjob == list_pipe_job)
|
||||||
|
|
20
Src/jobs.c
20
Src/jobs.c
|
@ -1718,8 +1718,15 @@ clearjobtab(int monitor)
|
||||||
/* Don't report any job we're part of */
|
/* Don't report any job we're part of */
|
||||||
if (thisjob != -1 && thisjob < oldmaxjob)
|
if (thisjob != -1 && thisjob < oldmaxjob)
|
||||||
memset(oldjobtab+thisjob, 0, sizeof(struct job));
|
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 */
|
memset(jobtab, 0, jobtabsize * sizeof(struct job)); /* zero out table */
|
||||||
maxjob = 0;
|
maxjob = 0;
|
||||||
|
|
||||||
|
@ -1733,6 +1740,18 @@ clearjobtab(int monitor)
|
||||||
thisjob = initjob();
|
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)
|
static int initnewjob(int i)
|
||||||
{
|
{
|
||||||
jobtab[i].stat = STAT_INUSE;
|
jobtab[i].stat = STAT_INUSE;
|
||||||
|
@ -2449,6 +2468,7 @@ bin_fg(char *name, char **argv, Options ops, int func)
|
||||||
case BIN_BG:
|
case BIN_BG:
|
||||||
case BIN_WAIT:
|
case BIN_WAIT:
|
||||||
if (func == BIN_BG) {
|
if (func == BIN_BG) {
|
||||||
|
clearoldjobtab();
|
||||||
jobtab[job].stat |= STAT_NOSTTY;
|
jobtab[job].stat |= STAT_NOSTTY;
|
||||||
jobtab[job].stat &= ~STAT_CURSH;
|
jobtab[job].stat &= ~STAT_CURSH;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,3 +48,31 @@
|
||||||
*>running:+:*=running
|
*>running:+:*=running
|
||||||
*>running:+:*=running
|
*>running:+:*=running
|
||||||
*>zsh:*SIGHUPed*
|
*>zsh:*SIGHUPed*
|
||||||
|
|
||||||
|
# $jobstates refers to a job started in the main shell unless
|
||||||
|
# one has been started in the subshell. In the latter case,
|
||||||
|
# the subshell has no job control so the job is not marked as current.
|
||||||
|
zpty_start
|
||||||
|
zpty_input "MODULE_PATH=${(q)MODULE_PATH}"
|
||||||
|
zpty_input 'sleep 3 &'
|
||||||
|
zpty_input '(print main; print $jobstates; sleep 2& print sub; print $jobstates)'
|
||||||
|
zpty_input 'jobs -s'
|
||||||
|
zpty_stop
|
||||||
|
0:$jobstate shows one job started in main shell or one started in subshell
|
||||||
|
*>\[1] [0-9]##
|
||||||
|
>main
|
||||||
|
*>running:+:*=running
|
||||||
|
>sub
|
||||||
|
*>running::*=running
|
||||||
|
*>zsh:*SIGHUPed*
|
||||||
|
|
||||||
|
# output from zpty removes empty lines
|
||||||
|
zpty_start
|
||||||
|
zpty_input "MODULE_PATH=${(q)MODULE_PATH}"
|
||||||
|
zpty_input '(print main; print $jobstates; sleep 2& print sub; print $jobstates)'
|
||||||
|
zpty_input 'jobs -s'
|
||||||
|
zpty_stop
|
||||||
|
0:$jobstate shows no job started in main shell but one started in subshell
|
||||||
|
>main
|
||||||
|
>sub
|
||||||
|
*>running::*=running
|
||||||
|
|
Loading…
Reference in a new issue