Re: PATCH: subshell into a new process group
"Anthony Heading" <[email protected]>
| Newsgroups | gmane.comp.shells.zsh.devel |
|---|---|
| Message-ID | <[email protected]> |
On Sun, May 10, 2026, at 2:29 AM, Bart Schaefer wrote: > Not at a shell right now but I'm pretty sure the way to do this is ( > print this is a new pgrp ) &! > I believe I'd found this only works in MONITOR mode, so yes, with job monitoring enabled, all backgrounded pipeline get a new pgid, disowned or not. But monitor mode is a feature of interactive shells and managing terminal access, it need a controlling terminal, it's pretty chatty, etc. For non-interactive shells, I don't think that & vs &! makes any difference, it just affects whether the job escapes the job table and thus avoids being SIGHUPed and so on. But it would seem intuitive that your idea should work. Do we imagine anyone currently uses &! in a non-interactive shell and expects the subshell would stay in the same process group? 'disown' does feel like the broad purpose is to push the child out of the nest. So maybe something like the attached?
disown-pgrp.patch
(text/x-patch, 1.1 KB)
diff --git Src/exec.c Src/exec.c
index 47d70b5a9..06e72e54f 100644
--- Src/exec.c
+++ Src/exec.c
@@ -1070,7 +1070,9 @@ enum {
/* Don't handle the MONITOR option even if previously set */
ESUB_NOMONITOR = 0x20,
/* This is a subshell where job control is allowed */
- ESUB_JOB_CONTROL = 0x40
+ ESUB_JOB_CONTROL = 0x40,
+ /* Job was started with &! — place in new process group even without MONITOR */
+ ESUB_DISOWN = 0x80
};
/*
@@ -1099,6 +1101,8 @@ entersubsh(int flags, struct entersubsh_ret *retp)
if (flags & ESUB_ASYNC) {
settrap(SIGINT, NULL, 0);
settrap(SIGQUIT, NULL, 0);
+ if (flags & ESUB_DISOWN)
+ setpgrp(0, 0);
if (isatty(0)) {
close(0);
if (open("/dev/null", O_RDWR | O_NOCTTY)) {
@@ -2859,7 +2863,8 @@ execcmd_fork(Estate state, int how, int type, Wordcode varspc,
/* pid == 0 */
close(synch[0]);
- flags = ((how & Z_ASYNC) ? ESUB_ASYNC : 0) | ESUB_PGRP;
+ flags = ((how & Z_ASYNC) ? ESUB_ASYNC : 0) | ESUB_PGRP |
+ ((how & Z_DISOWN) ? ESUB_DISOWN : 0);
if ((type != WC_SUBSH) && !(how & Z_ASYNC))
flags |= ESUB_KEEPTRAP;
if (type == WC_SUBSH && !(how & Z_ASYNC))