Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: subshell into a new process group
- X-seq: zsh-workers 54508
- From: "Anthony Heading" <ajrh@xxxxxxxx>
- To: zsh-workers@xxxxxxx
- Subject: PATCH: subshell into a new process group
- Date: Sat, 09 May 2026 13:15:36 +0900
- Archived-at: <https://zsh.org/workers/54508>
- Feedback-id: i6aa94791:Fastmail
- List-id: <zsh-workers.zsh.org>
Hi,
I have found this feature useful to allow signals to be sent to precisely bounded subshell trees. I couldn't find any existing way to achieve it; only the job code and zpty seem be close but neither of them allows exactly this. There's a bit of bikeshed argument about the name, the old argument-less setpgrp in SysV style is closer in spirit but it obsolescent and inconsistent with BSD, something less cryptic overall might be helpful but the zsystem module if it's the right home tends be be OS level. Anyway, I'm interested in pre-existing solutions or whether this is a useful feature as is.
Regards
Anthony
diff --git Doc/Zsh/mod_system.yo Doc/Zsh/mod_system.yo
index e25201faa..024ffc68f 100644
--- Doc/Zsh/mod_system.yo
+++ Doc/Zsh/mod_system.yo
@@ -158,6 +158,17 @@ to the command, or 2 for an error on the seek; no error message is
printed in the last case, but the parameter tt(ERRNO) reflects
the error that occurred.
)
+findex(syssetpgid)
+item(tt(syssetpgid))(
+This command places the current process in a new process group.
+
+This does not enable shell job control or change the terminal's
+foreground process group.
+
+The return status is 0 on success, 1 if any arguments were supplied, and 2
+if the underlying system call failed. In the last case, the parameter
+tt(ERRNO) reflects the error returned by the system.
+)
item(tt(syswrite) [ tt(-c) var(countvar) ] [ tt(-o) var(outfd) ] var(data))(
The data (a single string of bytes) are written to the file descriptor
var(outfd), or 1 if that is not given, using the tt(write) system call.
diff --git Src/Modules/system.c Src/Modules/system.c
index f1c0d7042..7bdcb6436 100644
--- Src/Modules/system.c
+++ Src/Modules/system.c
@@ -480,6 +480,28 @@ math_systell(UNUSED(char *name), UNUSED(int argc), mnumber *argv, UNUSED(int id)
}
+/*
+ * Return values of bin_syssetpgid:
+ * 0 Successfully changed process group
+ * 1 Error in parameters to command
+ * 2 Error from setpgrp(), ERRNO set by system
+ */
+
+/**/
+static int
+bin_syssetpgid(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
+{
+ errno = 0;
+
+ if (*args) {
+ zwarnnam(nam, "too many arguments");
+ return 1;
+ }
+
+ return setpgrp(0, 0) == -1 ? 2 : 0;
+}
+
+
/*
* Return values of bin_syserror:
* 0 Successfully processed error
@@ -821,6 +843,7 @@ static struct builtin bintab[] = {
BUILTIN("syswrite", 0, bin_syswrite, 1, 1, 0, "c:o:", NULL),
BUILTIN("sysopen", 0, bin_sysopen, 1, 1, 0, "rwau:o:m:", NULL),
BUILTIN("sysseek", 0, bin_sysseek, 1, 1, 0, "u:w:", NULL),
+ BUILTIN("syssetpgid", 0, bin_syssetpgid, 0, 0, 0, "", NULL),
BUILTIN("zsystem", 0, bin_zsystem, 1, -1, 0, NULL, NULL)
};
diff --git Src/Modules/system.mdd Src/Modules/system.mdd
index 00a3e7896..4a282eedc 100644
--- Src/Modules/system.mdd
+++ Src/Modules/system.mdd
@@ -2,7 +2,7 @@ name=zsh/system
link=dynamic
load=no
-autofeatures="b:sysread b:syswrite b:sysopen b:sysseek b:syserror p:errnos f:systell"
+autofeatures="b:sysread b:syswrite b:sysopen b:sysseek b:syssetpgid b:syserror p:errnos f:systell"
objects="system.o errnames.o"
diff --git Test/V01zmodload.ztst Test/V01zmodload.ztst
index daf49cd72..db15e15a9 100644
--- Test/V01zmodload.ztst
+++ Test/V01zmodload.ztst
@@ -288,6 +288,7 @@
0:Regression tests for index bug with math functions.
>+b:syserror
>+b:sysread
+>+b:syssetpgid
>+b:syswrite
>+b:sysopen
>+b:sysseek
@@ -298,6 +299,7 @@
>0
>+b:syserror
>+b:sysread
+>+b:syssetpgid
>+b:syswrite
>+b:sysopen
>+b:sysseek
@@ -308,6 +310,7 @@
>1
>+b:syserror
>+b:sysread
+>+b:syssetpgid
>+b:syswrite
>+b:sysopen
>+b:sysseek
@@ -329,6 +332,7 @@
1:Module Features for math functions
>+b:syserror
>+b:sysread
+>+b:syssetpgid
>+b:syswrite
>+b:sysopen
>+b:sysseek
@@ -338,6 +342,7 @@
>+p:sysparams
>+b:syserror
>+b:sysread
+>+b:syssetpgid
>+b:syswrite
>+b:sysopen
>+b:sysseek
diff --git Test/V14system.ztst Test/V14system.ztst
index bcabe4082..a023794a6 100644
--- Test/V14system.ztst
+++ Test/V14system.ztst
@@ -223,3 +223,7 @@ F:The value of $REPLY should be empty or unset when nothing is read?
F:The value of $oration should be empty or unset when everything is written?
>a few words
>12 xx
+
+ syssetpgid unexpected
+1:syssetpgid rejects arguments
+?(eval):syssetpgid:1: too many arguments
Messages sorted by:
Reverse Date,
Date,
Thread,
Author