(fd: BorrowedFd<'_>)
| 55 | #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] |
| 56 | #[cold] |
| 57 | fn tcgetattr_fallback(fd: BorrowedFd<'_>) -> io::Result<Termios> { |
| 58 | use core::ptr::{addr_of, addr_of_mut}; |
| 59 | |
| 60 | let mut result = MaybeUninit::<Termios>::uninit(); |
| 61 | |
| 62 | // SAFETY: This invokes the `TCGETS` ioctl which initializes the `Termios` |
| 63 | // structure except for the `input_speed` and `output_speed` fields, which |
| 64 | // we manually initialize before forming a reference to the full `Termios`. |
| 65 | unsafe { |
| 66 | // Do the old `TCGETS` call. |
| 67 | ret(syscall!(__NR_ioctl, fd, c_uint(c::TCGETS), &mut result))?; |
| 68 | |
| 69 | // Read the `control_modes` field without forming a reference to the |
| 70 | // `Termios` because it isn't fully initialized yet. |
| 71 | let ptr = result.as_mut_ptr(); |
| 72 | let control_modes = addr_of!((*ptr).control_modes).read(); |
| 73 | |
| 74 | // Infer the output speed and set `output_speed`. |
| 75 | let encoded_out = control_modes.bits() & c::CBAUD; |
| 76 | let output_speed = match speed::decode(encoded_out) { |
| 77 | Some(output_speed) => output_speed, |
| 78 | None => return Err(io::Errno::RANGE), |
| 79 | }; |
| 80 | addr_of_mut!((*ptr).output_speed).write(output_speed); |
| 81 | |
| 82 | // Infer the input speed and set `input_speed`. `B0` is a special-case |
| 83 | // that means the input speed is the same as the output speed. |
| 84 | let encoded_in = (control_modes.bits() & c::CIBAUD) >> c::IBSHIFT; |
| 85 | let input_speed = if encoded_in == c::B0 { |
| 86 | output_speed |
| 87 | } else { |
| 88 | match speed::decode(encoded_in) { |
| 89 | Some(input_speed) => input_speed, |
| 90 | None => return Err(io::Errno::RANGE), |
| 91 | } |
| 92 | }; |
| 93 | addr_of_mut!((*ptr).input_speed).write(input_speed); |
| 94 | |
| 95 | // Now all the fields are set. |
| 96 | Ok(result.assume_init()) |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | #[inline] |
| 101 | pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result<Pid> { |
no test coverage detected