authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-07-22 11:17:18-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-07-22 11:17:18-07:00
logeac7fd4da5992299a1f2fb59c5aa237c0c6c6761
treea47ca2b7ae4e9395ebe99dd7488f367a727e991c
parent1fc42ed3e7ca0b74b54aaa827276d995d6c7c6cd
parent759ab41d725604c38fea9be658fe93f046f59293
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #20556 from McSinyx/setpgid

Allow setting PGID in std.process.Child.spawn

4 files changed, 32 insertions(+), 0 deletions(-)

lib/std/c.zig+1
......@@ -9167,6 +9167,7 @@ pub extern "c" fn setreuid(ruid: uid_t, euid: uid_t) c_int;
91679167pub extern "c" fn setregid(rgid: gid_t, egid: gid_t) c_int;
91689168pub extern "c" fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) c_int;
91699169pub extern "c" fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) c_int;
9170pub extern "c" fn setpgid(pid: pid_t, pgid: pid_t) c_int;
91709171
91719172pub extern "c" fn malloc(usize) ?*anyopaque;
91729173pub extern "c" fn realloc(?*anyopaque, usize) ?*anyopaque;
lib/std/os/linux.zig+4
......@@ -1551,6 +1551,10 @@ pub fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) usize {
15511551 }
15521552}
15531553
1554pub fn setpgid(pid: pid_t, pgid: pid_t) usize {
1555 return syscall2(.setpgid, @intCast(pid), @intCast(pgid));
1556}
1557
15541558pub fn getgroups(size: usize, list: *gid_t) usize {
15551559 if (@hasField(SYS, "getgroups32")) {
15561560 return syscall2(.getgroups32, size, @intFromPtr(list));
lib/std/posix.zig+18
......@@ -3415,6 +3415,24 @@ pub fn setregid(rgid: gid_t, egid: gid_t) SetIdError!void {
34153415 }
34163416}
34173417
3418pub const SetPgidError = error{
3419 ProcessAlreadyExec,
3420 InvalidProcessGroupId,
3421 PermissionDenied,
3422 ProcessNotFound,
3423} || UnexpectedError;
3424
3425pub 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.
34193437pub fn isatty(handle: fd_t) bool {
34203438 if (native_os == .windows) {
lib/std/process/Child.zig+9
......@@ -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.
6464gid: 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.
67pgid: 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.
6770cwd: ?[]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),