Skip to content

Commit eac7fd4

Browse files
authored
Merge pull request #20556 from McSinyx/setpgid
Allow setting PGID in std.process.Child.spawn
2 parents 1fc42ed + 759ab41 commit eac7fd4

File tree

4 files changed

+32
-0
lines changed

4 files changed

+32
-0
lines changed

lib/std/c.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9167,6 +9167,7 @@ pub extern "c" fn setreuid(ruid: uid_t, euid: uid_t) c_int;
91679167
pub extern "c" fn setregid(rgid: gid_t, egid: gid_t) c_int;
91689168
pub extern "c" fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) c_int;
91699169
pub extern "c" fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) c_int;
9170+
pub extern "c" fn setpgid(pid: pid_t, pgid: pid_t) c_int;
91709171

91719172
pub extern "c" fn malloc(usize) ?*anyopaque;
91729173
pub extern "c" fn realloc(?*anyopaque, usize) ?*anyopaque;

lib/std/os/linux.zig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,6 +1551,10 @@ pub fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) usize {
15511551
}
15521552
}
15531553

1554+
pub fn setpgid(pid: pid_t, pgid: pid_t) usize {
1555+
return syscall2(.setpgid, @intCast(pid), @intCast(pgid));
1556+
}
1557+
15541558
pub fn getgroups(size: usize, list: *gid_t) usize {
15551559
if (@hasField(SYS, "getgroups32")) {
15561560
return syscall2(.getgroups32, size, @intFromPtr(list));

lib/std/posix.zig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3415,6 +3415,24 @@ pub fn setregid(rgid: gid_t, egid: gid_t) SetIdError!void {
34153415
}
34163416
}
34173417

3418+
pub const SetPgidError = error{
3419+
ProcessAlreadyExec,
3420+
InvalidProcessGroupId,
3421+
PermissionDenied,
3422+
ProcessNotFound,
3423+
} || UnexpectedError;
3424+
3425+
pub fn setpgid(pid: pid_t, pgid: pid_t) SetPgidError!void {
3426+
switch (errno(system.setpgid(pid, pgid))) {
3427+
.SUCCESS => return,
3428+
.ACCES => return error.ProcessAlreadyExec,
3429+
.INVAL => return error.InvalidProcessGroupId,
3430+
.PERM => return error.PermissionDenied,
3431+
.SRCH => return error.ProcessNotFound,
3432+
else => |err| return unexpectedErrno(err),
3433+
}
3434+
}
3435+
34183436
/// Test whether a file descriptor refers to a terminal.
34193437
pub fn isatty(handle: fd_t) bool {
34203438
if (native_os == .windows) {

lib/std/process/Child.zig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ uid: if (native_os == .windows or native_os == .wasi) void else ?posix.uid_t,
6363
/// Set to change the group id when spawning the child process.
6464
gid: if (native_os == .windows or native_os == .wasi) void else ?posix.gid_t,
6565

66+
/// Set to change the process group id when spawning the child process.
67+
pgid: if (native_os == .windows or native_os == .wasi) void else ?posix.pid_t,
68+
6669
/// Set to change the current working directory when spawning the child process.
6770
cwd: ?[]const u8,
6871
/// Set to change the current working directory when spawning the child process.
@@ -168,6 +171,7 @@ pub const SpawnError = error{
168171
} ||
169172
posix.ExecveError ||
170173
posix.SetIdError ||
174+
posix.SetPgidError ||
171175
posix.ChangeCurDirError ||
172176
windows.CreateProcessError ||
173177
windows.GetProcessMemoryInfoError ||
@@ -213,6 +217,7 @@ pub fn init(argv: []const []const u8, allocator: mem.Allocator) ChildProcess {
213217
.cwd = null,
214218
.uid = if (native_os == .windows or native_os == .wasi) {} else null,
215219
.gid = if (native_os == .windows or native_os == .wasi) {} else null,
220+
.pgid = if (native_os == .windows or native_os == .wasi) {} else null,
216221
.stdin = null,
217222
.stdout = null,
218223
.stderr = null,
@@ -675,6 +680,10 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void {
675680
posix.setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err);
676681
}
677682

683+
if (self.pgid) |pid| {
684+
posix.setpgid(0, pid) catch |err| forkChildErrReport(err_pipe[1], err);
685+
}
686+
678687
const err = switch (self.expand_arg0) {
679688
.expand => posix.execvpeZ_expandArg0(.expand, argv_buf.ptr[0].?, argv_buf.ptr, envp),
680689
.no_expand => posix.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp),

0 commit comments

Comments
 (0)