diff options
| -rw-r--r-- | ChangeLog | 3 | ||||
| -rw-r--r-- | Doc/Zsh/builtins.yo | 3 | ||||
| -rw-r--r-- | Src/builtin.c | 2 | ||||
| -rw-r--r-- | Src/jobs.c | 14 | ||||
| -rw-r--r-- | Test/W02jobs.ztst | 13 |
5 files changed, 31 insertions, 4 deletions
@@ -1,5 +1,8 @@ 2026-05-23 dana <dana@dana.is> + * 54585: Doc/Zsh/builtins.yo, Src/builtin.c, Src/jobs.c, + Test/W02jobs.ztst: disown: add -a option + * 54584: Src/jobs.c, Test/W02jobs.ztst, Test/W03jobparameters.ztst: jobs: update curjob in sub-shells diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 095bc5783..dbd96c6c0 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -464,13 +464,14 @@ enditem() ) findex(disown) cindex(jobs, disowning) -xitem(tt(disown) [ var(job) ... ]) +xitem(tt(disown) [ tt(-a) | var(job) ... ]) xitem(var(job) ... tt(&|)) item(var(job) ... tt(&!))( Remove the specified var(job)s from the job table; the shell will no longer report their status, and will not complain if you try to exit an interactive shell with them running or stopped. If no var(job) is specified, disown the current job. +With tt(-a), disown all jobs. If the var(job)s are currently stopped and the tt(AUTO_CONTINUE) option is not set, a warning is printed containing information about how to diff --git a/Src/builtin.c b/Src/builtin.c index 706191832..864b9d70f 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -58,7 +58,7 @@ static struct builtin builtins[] = BUILTIN("declare", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klmnp:%rtuxz", NULL), BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "clpv", NULL), BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmprs", NULL), - BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL), + BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, "a", NULL), BUILTIN("echo", BINF_SKIPINVALID, bin_print, 0, -1, BIN_ECHO, "neE", "-"), BUILTIN("emulate", 0, bin_emulate, 0, -1, 0, "lLR", NULL), BUILTIN("enable", 0, bin_enable, 0, -1, BIN_ENABLE, "afmprs", NULL), diff --git a/Src/jobs.c b/Src/jobs.c index 2661ea0c1..03987d436 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -2419,6 +2419,12 @@ int bin_fg(char *name, char **argv, Options ops, int func) { int job, lng, firstjob = -1, retval = 0, ofunc = func; + int disown_all = (func == BIN_DISOWN && OPT_ISSET(ops, 'a')); + + if (disown_all && *argv) { + zwarnnam(name, "argument not meaningful with -a: %s", *argv); + return 1; + } if (OPT_ISSET(ops,'Z')) { int len; @@ -2483,10 +2489,12 @@ bin_fg(char *name, char **argv, Options ops, int func) * will prevent zexit from complaining about stopped jobs */ stopmsg = 2; if (!*argv) { + if (disown_all) { + firstjob = 0; /* This block handles all of the default cases (no arguments). bg, fg and disown act on the current job, and jobs and wait act on all the jobs. */ - if (func == BIN_FG || func == BIN_BG || func == BIN_DISOWN) { + } else if (func == BIN_FG || func == BIN_BG || func == BIN_DISOWN) { /* W.r.t. the above comment, we'd better have a current job at this point or else. */ if (curjob == -1 || (jobtab[curjob].stat & STAT_NOPRINT)) { @@ -2574,7 +2582,7 @@ bin_fg(char *name, char **argv, Options ops, int func) } /* The only type of argument allowed now is a job spec. Check it. */ job = (*argv) ? getjob(*argv, name) : firstjob; - firstjob = -1; + firstjob = (disown_all && job <= maxjob) ? job + 1 : -1; if (job == -1) { retval = 127; break; @@ -2582,6 +2590,8 @@ bin_fg(char *name, char **argv, Options ops, int func) jstat = oldjobtab ? oldjobtab[job].stat : jobtab[job].stat; if (!(jstat & STAT_INUSE) || (jstat & STAT_NOPRINT)) { + if (disown_all) + continue; if (!isset(POSIXBUILTINS)) zwarnnam(name, "%s: no such job", *argv); unqueue_signals(); diff --git a/Test/W02jobs.ztst b/Test/W02jobs.ztst index 135869d81..f38e90dcd 100644 --- a/Test/W02jobs.ztst +++ b/Test/W02jobs.ztst @@ -274,6 +274,19 @@ #*>disown: warning: job is suspended* zpty_start + zpty_input 'sleep 2 &; sleep 3 &; sleep 4 &; disown -a; jobs' + zpty_stop +0:disown -a +*>\[1] <-> +*>\[2] <-> +*>\[3] <-> + + zpty_start + zpty_input '( sleep 2 &; sleep 3 &; sleep 4 &; disown -a; jobs ); :' + zpty_stop +0:disown -a in sub-shell + + zpty_start zpty_input 'sleep 2 &; sleep 3 &|; jobs; disown' zpty_input 'sleep 2 &; sleep 3 &!; jobs; disown' zpty_stop |
