diff --git a/src/backend/libc/termios/syscalls.rs b/src/backend/libc/termios/syscalls.rs index dbe4a6e03..5278a989c 100644 --- a/src/backend/libc/termios/syscalls.rs +++ b/src/backend/libc/termios/syscalls.rs @@ -167,10 +167,9 @@ pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result { unsafe { let pid = ret_pid_t(c::tcgetpgrp(borrowed_fd(fd)))?; - // This doesn't appear to be documented, but on Linux, it appears - // `tcsetpgrp` can succeed and set the pid to 0 if we pass it a - // pseudo-terminal device fd. For now, translate it into `OPNOTSUPP`. - #[cfg(linux_kernel)] + // On some platforms, a pseudo-terminal without a foreground process + // group returns 0, which `Pid` cannot represent. Translate this into + // `OPNOTSUPP`, as in the linux_raw backend. if pid == 0 { return Err(io::Errno::OPNOTSUPP); } diff --git a/src/termios/tc.rs b/src/termios/tc.rs index dabd17eb7..c21b3dc20 100644 --- a/src/termios/tc.rs +++ b/src/termios/tc.rs @@ -55,7 +55,7 @@ pub fn tcgetwinsize(fd: Fd) -> io::Result { /// /// Also known as the `TIOCGPGRP` operation with `ioctl`. /// -/// On Linux, if `fd` is a pseudo-terminal, the underlying system call here can +/// If `fd` is a pseudo-terminal, the underlying system call here can /// return a pid of 0, which rustix's `Pid` type doesn't support. So rustix /// instead handles this case by failing with [`io::Errno::OPNOTSUPP`] if the /// pid is 0. diff --git a/tests/termios/pgrp.rs b/tests/termios/pgrp.rs index 80b8cc3c7..af0bffc0e 100644 --- a/tests/termios/pgrp.rs +++ b/tests/termios/pgrp.rs @@ -33,15 +33,15 @@ fn pgrp_pseudoterminal() { Err(err) => panic!("{:?}", err), }; - // Linux's `tcgetpgrp` returns 0 here, which is not documented, so rustix - // translates it into `OPNOTSUPP`. - #[cfg(linux_kernel)] + // Linux's and Apple's `tcgetpgrp` return 0 here, which is not documented, + // so rustix translates it into `OPNOTSUPP`. + #[cfg(any(linux_kernel, apple))] assert_eq!(tcgetpgrp(&pty), Err(rustix::io::Errno::OPNOTSUPP)); // FreeBSD's `tcgetpgrp` returns 100000 here, or presumably some other // number if that number is already taken, which is documented behavior, // but impossible to test for reliably. - #[cfg(not(linux_kernel))] + #[cfg(not(any(linux_kernel, apple)))] assert!(matches!(tcgetpgrp(&pty), Ok(_))); // We shouldn't be able to set the process group to [`Pid::INIT`].