summaryrefslogtreecommitdiffstats
path: root/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rustix/src/backend/linux_raw/termios/syscalls.rs')
-rw-r--r--vendor/rustix/src/backend/linux_raw/termios/syscalls.rs42
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`.