Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: PATCH: subshell into a new process group



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?
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))


Messages sorted by: Reverse Date, Date, Thread, Author