| author | |
| committer | |
| log | eac7fd4da5992299a1f2fb59c5aa237c0c6c6761 |
| tree | a47ca2b7ae4e9395ebe99dd7488f367a727e991c |
| parent | 1fc42ed3e7ca0b74b54aaa827276d995d6c7c6cd |
| parent | 759ab41d725604c38fea9be658fe93f046f59293 |
| signature |
Allow setting PGID in std.process.Child.spawn4 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; | ... | @@ -9167,6 +9167,7 @@ pub extern "c" fn setreuid(ruid: uid_t, euid: uid_t) c_int; |
| 9167 | pub extern "c" fn setregid(rgid: gid_t, egid: gid_t) c_int; | 9167 | pub extern "c" fn setregid(rgid: gid_t, egid: gid_t) c_int; |
| 9168 | pub extern "c" fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) c_int; | 9168 | pub extern "c" fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) c_int; |
| 9169 | pub extern "c" fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) c_int; | 9169 | 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; | ||
| 9170 | 9171 | ||
| 9171 | pub extern "c" fn malloc(usize) ?*anyopaque; | 9172 | pub extern "c" fn malloc(usize) ?*anyopaque; |
| 9172 | pub extern "c" fn realloc(?*anyopaque, usize) ?*anyopaque; | 9173 | pub 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 { | ... | @@ -1551,6 +1551,10 @@ pub fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) usize { |
| 1551 | } | 1551 | } |
| 1552 | } | 1552 | } |
| 1553 | 1553 | ||
| 1554 | pub fn setpgid(pid: pid_t, pgid: pid_t) usize { | ||
| 1555 | return syscall2(.setpgid, @intCast(pid), @intCast(pgid)); | ||
| 1556 | } | ||
| 1557 | |||
| 1554 | pub fn getgroups(size: usize, list: *gid_t) usize { | 1558 | pub fn getgroups(size: usize, list: *gid_t) usize { |
| 1555 | if (@hasField(SYS, "getgroups32")) { | 1559 | if (@hasField(SYS, "getgroups32")) { |
| 1556 | return syscall2(.getgroups32, size, @intFromPtr(list)); | 1560 | 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 { | ... | @@ -3415,6 +3415,24 @@ pub fn setregid(rgid: gid_t, egid: gid_t) SetIdError!void { |
| 3415 | } | 3415 | } |
| 3416 | } | 3416 | } |
| 3417 | 3417 | ||
| 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 | |||
| 3418 | /// Test whether a file descriptor refers to a terminal. | 3436 | /// Test whether a file descriptor refers to a terminal. |
| 3419 | pub fn isatty(handle: fd_t) bool { | 3437 | pub fn isatty(handle: fd_t) bool { |
| 3420 | if (native_os == .windows) { | 3438 | 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, | ... | @@ -63,6 +63,9 @@ uid: if (native_os == .windows or native_os == .wasi) void else ?posix.uid_t, |
| 63 | /// Set to change the group id when spawning the child process. | 63 | /// Set to change the group id when spawning the child process. |
| 64 | gid: if (native_os == .windows or native_os == .wasi) void else ?posix.gid_t, | 64 | gid: if (native_os == .windows or native_os == .wasi) void else ?posix.gid_t, |
| 65 | 65 | ||
| 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 | |||
| 66 | /// Set to change the current working directory when spawning the child process. | 69 | /// Set to change the current working directory when spawning the child process. |
| 67 | cwd: ?[]const u8, | 70 | cwd: ?[]const u8, |
| 68 | /// Set to change the current working directory when spawning the child process. | 71 | /// Set to change the current working directory when spawning the child process. |
| ... | @@ -168,6 +171,7 @@ pub const SpawnError = error{ | ... | @@ -168,6 +171,7 @@ pub const SpawnError = error{ |
| 168 | } || | 171 | } || |
| 169 | posix.ExecveError || | 172 | posix.ExecveError || |
| 170 | posix.SetIdError || | 173 | posix.SetIdError || |
| 174 | posix.SetPgidError || | ||
| 171 | posix.ChangeCurDirError || | 175 | posix.ChangeCurDirError || |
| 172 | windows.CreateProcessError || | 176 | windows.CreateProcessError || |
| 173 | windows.GetProcessMemoryInfoError || | 177 | windows.GetProcessMemoryInfoError || |
| ... | @@ -213,6 +217,7 @@ pub fn init(argv: []const []const u8, allocator: mem.Allocator) ChildProcess { | ... | @@ -213,6 +217,7 @@ pub fn init(argv: []const []const u8, allocator: mem.Allocator) ChildProcess { |
| 213 | .cwd = null, | 217 | .cwd = null, |
| 214 | .uid = if (native_os == .windows or native_os == .wasi) {} else null, | 218 | .uid = if (native_os == .windows or native_os == .wasi) {} else null, |
| 215 | .gid = if (native_os == .windows or native_os == .wasi) {} else null, | 219 | .gid = if (native_os == .windows or native_os == .wasi) {} else null, |
| 220 | .pgid = if (native_os == .windows or native_os == .wasi) {} else null, | ||
| 216 | .stdin = null, | 221 | .stdin = null, |
| 217 | .stdout = null, | 222 | .stdout = null, |
| 218 | .stderr = null, | 223 | .stderr = null, |
| ... | @@ -675,6 +680,10 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void { | ... | @@ -675,6 +680,10 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void { |
| 675 | posix.setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err); | 680 | posix.setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err); |
| 676 | } | 681 | } |
| 677 | 682 | ||
| 683 | if (self.pgid) |pid| { | ||
| 684 | posix.setpgid(0, pid) catch |err| forkChildErrReport(err_pipe[1], err); | ||
| 685 | } | ||
| 686 | |||
| 678 | const err = switch (self.expand_arg0) { | 687 | const err = switch (self.expand_arg0) { |
| 679 | .expand => posix.execvpeZ_expandArg0(.expand, argv_buf.ptr[0].?, argv_buf.ptr, envp), | 688 | .expand => posix.execvpeZ_expandArg0(.expand, argv_buf.ptr[0].?, argv_buf.ptr, envp), |
| 680 | .no_expand => posix.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp), | 689 | .no_expand => posix.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp), |