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))
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.