diff options
Diffstat (limited to 'vendor/rustix/src/backend/linux_raw/termios/syscalls.rs')
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/termios/syscalls.rs | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs b/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs index 09100441f..d2fe91236 100644 --- a/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs @@ -37,8 +37,46 @@ pub(crate) fn tcgetwinsize(fd: BorrowedFd<'_>) -> io::Result<Winsize> { pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result<Termios> { unsafe { let mut result = MaybeUninit::<Termios>::uninit(); + + // QEMU's `TCGETS2` doesn't currently set `input_speed` or + // `output_speed` on PowerPC, so zero out the fields ourselves. + #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] + { + result.write(core::mem::zeroed()); + } + ret(syscall!(__NR_ioctl, fd, c_uint(c::TCGETS2), &mut result))?; - Ok(result.assume_init()) + + let result = result.assume_init(); + + // QEMU's `TCGETS2` doesn't currently set `input_speed` or + // `output_speed` on PowerPC, so set them manually if we can. + #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] + let result = { + use crate::termios::speed; + let mut result = result; + if result.output_speed == 0 && (result.control_modes.bits() & c::CBAUD) != c::BOTHER { + if let Some(output_speed) = speed::decode(result.control_modes.bits() & c::CBAUD) { + result.output_speed = output_speed; + } + } + if result.input_speed == 0 + && ((result.control_modes.bits() & c::CIBAUD) >> c::IBSHIFT) != c::BOTHER + { + // For input speeds, `B0` is special-cased to mean the input + // speed is the same as the output speed. + if ((result.control_modes.bits() & c::CIBAUD) >> c::IBSHIFT) == c::B0 { + result.input_speed = result.output_speed; + } else if let Some(input_speed) = + speed::decode((result.control_modes.bits() & c::CIBAUD) >> c::IBSHIFT) + { + result.input_speed = input_speed; + } + } + result + }; + + Ok(result) } } @@ -240,7 +278,7 @@ pub(crate) fn ttyname(fd: BorrowedFd<'_>, buf: &mut [MaybeUninit<u8>]) -> io::Re // Check that `fd` is really a tty. tcgetwinsize(fd)?; - // Get a fd to '/proc/self/fd'. + // Get a fd to "/proc/self/fd". let proc_self_fd = procfs::proc_self_fd()?; // Gather the ttyname by reading the "fd" file inside `proc_self_fd`. |