Commit aa9ea61216
lib/std/os/linux.zig
@@ -1631,6 +1631,14 @@ pub fn tcsetattr(fd: fd_t, optional_action: TCSA, termios_p: *const termios) usi
return syscall3(.ioctl, @bitCast(usize, @as(isize, fd)), T.CSETS + @enumToInt(optional_action), @ptrToInt(termios_p));
}
+pub fn tcgetpgrp(fd: fd_t, pgrp: *pid_t) usize {
+ return syscall3(.ioctl, @bitCast(usize, @as(isize, fd)), T.IOCGPGRP, @ptrToInt(pgrp));
+}
+
+pub fn tcsetpgrp(fd: fd_t, pgrp: *const pid_t) usize {
+ return syscall3(.ioctl, @bitCast(usize, @as(isize, fd)), T.IOCSPGRP, @ptrToInt(pgrp));
+}
+
pub fn tcdrain(fd: fd_t) usize {
return syscall3(.ioctl, @bitCast(usize, @as(isize, fd)), T.CSBRK, 1);
}
lib/std/os.zig
@@ -6791,7 +6791,9 @@ pub fn getrusage(who: i32) rusage {
}
}
-pub const TermiosGetError = error{NotATerminal} || UnexpectedError;
+pub const TIOCError = error{NotATerminal};
+
+pub const TermiosGetError = TIOCError || UnexpectedError;
pub fn tcgetattr(handle: fd_t) TermiosGetError!termios {
while (true) {
@@ -6822,6 +6824,41 @@ pub fn tcsetattr(handle: fd_t, optional_action: TCSA, termios_p: termios) Termio
}
}
+pub const TermioGetPgrpError = TIOCError || UnexpectedError;
+
+/// Returns the process group ID for the TTY associated with the given handle.
+pub fn tcgetpgrp(handle: fd_t) TermioGetPgrpError!pid_t {
+ while (true) {
+ var pgrp: pid_t = undefined;
+ switch (errno(system.tcgetpgrp(handle, &pgrp))) {
+ .SUCCESS => return pgrp,
+ .BADF => unreachable,
+ .INVAL => unreachable,
+ .NOTTY => return error.NotATerminal,
+ else => |err| return unexpectedErrno(err),
+ }
+ }
+}
+
+pub const TermioSetPgrpError = TermioGetPgrpError || error{NotAPgrpMember};
+
+/// Sets the controlling process group ID for given TTY.
+/// handle must be valid fd_t to a TTY associated with calling process.
+/// pgrp must be a valid process group, and the calling process must be a member
+/// of that group.
+pub fn tcsetpgrp(handle: fd_t, pgrp: pid_t) TermioSetPgrpError!void {
+ while (true) {
+ switch (errno(system.tcsetpgrp(handle, &pgrp))) {
+ .SUCCESS => return,
+ .BADF => unreachable,
+ .INVAL => unreachable,
+ .NOTTY => return error.NotATerminal,
+ .PERM => return TermioSetPgrpError.NotAPgrpMember,
+ else => |err| return unexpectedErrno(err),
+ }
+ }
+}
+
pub const IoCtl_SIOCGIFINDEX_Error = error{
FileSystem,
InterfaceNotFound,