From f587a06a0d0d1f5adcb0319c5a30856d74d66786 Mon Sep 17 00:00:00 2001 From: Andrew Walbran Date: Thu, 7 Dec 2023 12:16:46 +0000 Subject: [PATCH 1/6] Use from_bits_retain for all Termios wrapper fields. In case there are any unrecognised bits, they should be kept when setting fields of the underlying libc termios struct in get_libc_termios, rather than being dropped. This ensures that termios can be roundtripped even with unrecognised bits set. --- src/sys/termios.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sys/termios.rs b/src/sys/termios.rs index bdddc0c735..eefbebb302 100644 --- a/src/sys/termios.rs +++ b/src/sys/termios.rs @@ -219,10 +219,10 @@ impl Termios { /// Updates the wrapper values from the internal `libc::termios` data structure. pub(crate) fn update_wrapper(&mut self) { let termios = *self.inner.borrow_mut(); - self.input_flags = InputFlags::from_bits_truncate(termios.c_iflag); - self.output_flags = OutputFlags::from_bits_truncate(termios.c_oflag); + self.input_flags = InputFlags::from_bits_retain(termios.c_iflag); + self.output_flags = OutputFlags::from_bits_retain(termios.c_oflag); self.control_flags = ControlFlags::from_bits_retain(termios.c_cflag); - self.local_flags = LocalFlags::from_bits_truncate(termios.c_lflag); + self.local_flags = LocalFlags::from_bits_retain(termios.c_lflag); self.control_chars = termios.c_cc; #[cfg(any(linux_android, target_os = "haiku"))] { @@ -235,10 +235,10 @@ impl From for Termios { fn from(termios: libc::termios) -> Self { Termios { inner: RefCell::new(termios), - input_flags: InputFlags::from_bits_truncate(termios.c_iflag), - output_flags: OutputFlags::from_bits_truncate(termios.c_oflag), - control_flags: ControlFlags::from_bits_truncate(termios.c_cflag), - local_flags: LocalFlags::from_bits_truncate(termios.c_lflag), + input_flags: InputFlags::from_bits_retain(termios.c_iflag), + output_flags: OutputFlags::from_bits_retain(termios.c_oflag), + control_flags: ControlFlags::from_bits_retain(termios.c_cflag), + local_flags: LocalFlags::from_bits_retain(termios.c_lflag), control_chars: termios.c_cc, #[cfg(any(linux_android, target_os = "haiku"))] line_discipline: termios.c_line, From 1d3f73c75a47f8f22d3202b7b2742f1a77752468 Mon Sep 17 00:00:00 2001 From: Andrew Walbran Date: Thu, 7 Dec 2023 14:48:00 +0000 Subject: [PATCH 2/6] Test round-tripping a termios with unrecognised flags. --- src/sys/termios.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/sys/termios.rs b/src/sys/termios.rs index eefbebb302..8cb1ffe5a4 100644 --- a/src/sys/termios.rs +++ b/src/sys/termios.rs @@ -932,4 +932,28 @@ mod test { #[cfg(target_os = "haiku")] BaudRate::try_from(99).expect_err("assertion failed"); } + + #[test] + fn roundtrip_termios() { + // A fake termios including flag bits which we don't recognise. + let original = libc::termios { + c_iflag: 0xf00f, + c_oflag: 0xd00d, + c_cflag: 0x6642, + c_lflag: 0x1234, + #[cfg(any(linux_android, target_os = "haiku"))] + c_line: 0x00, + c_cc: [0; NCCS], + c_ispeed: 0, + c_ospeed: 0, + }; + + let mut attrs: Termios = original.into(); + let before_update = attrs.get_libc_termios().to_owned(); + attrs.update_wrapper(); + let after_update = attrs.get_libc_termios().to_owned(); + + assert_eq!(before_update, original); + assert_eq!(after_update, original); + } } From a80096a28f1f8be2a3ef1581975ad070081f2af8 Mon Sep 17 00:00:00 2001 From: Andrew Walbran Date: Thu, 7 Dec 2023 14:56:41 +0000 Subject: [PATCH 3/6] Fix test build on musl. --- src/sys/termios.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sys/termios.rs b/src/sys/termios.rs index 8cb1ffe5a4..3b6456623d 100644 --- a/src/sys/termios.rs +++ b/src/sys/termios.rs @@ -944,8 +944,14 @@ mod test { #[cfg(any(linux_android, target_os = "haiku"))] c_line: 0x00, c_cc: [0; NCCS], + #[cfg(not(target_env = "musl"))] c_ispeed: 0, + #[cfg(not(target_env = "musl"))] c_ospeed: 0, + #[cfg(target_env = "musl")] + __c_ispeed: 0, + #[cfg(target_env = "musl")] + __c_ospeed: 0, }; let mut attrs: Termios = original.into(); From 5035f4c1eb41eadf502e66ba527f3288c475d550 Mon Sep 17 00:00:00 2001 From: Andrew Walbran Date: Thu, 7 Dec 2023 14:58:45 +0000 Subject: [PATCH 4/6] Add changelog entry. --- changelog/2253.fixed.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/2253.fixed.md diff --git a/changelog/2253.fixed.md b/changelog/2253.fixed.md new file mode 100644 index 0000000000..3e66e976d4 --- /dev/null +++ b/changelog/2253.fixed.md @@ -0,0 +1 @@ +Fixed roundtripping of libc `termios` with unknown flags through `Termios` wrapper. From b1a3e082c29c2db8d1ab42f9a55af48cf5821578 Mon Sep 17 00:00:00 2001 From: Andrew Walbran Date: Thu, 7 Dec 2023 15:04:39 +0000 Subject: [PATCH 5/6] Fix test on more platforms. --- src/sys/termios.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/sys/termios.rs b/src/sys/termios.rs index 3b6456623d..dbd75a932b 100644 --- a/src/sys/termios.rs +++ b/src/sys/termios.rs @@ -941,17 +941,8 @@ mod test { c_oflag: 0xd00d, c_cflag: 0x6642, c_lflag: 0x1234, - #[cfg(any(linux_android, target_os = "haiku"))] - c_line: 0x00, c_cc: [0; NCCS], - #[cfg(not(target_env = "musl"))] - c_ispeed: 0, - #[cfg(not(target_env = "musl"))] - c_ospeed: 0, - #[cfg(target_env = "musl")] - __c_ispeed: 0, - #[cfg(target_env = "musl")] - __c_ospeed: 0, + ..unsafe { std::mem::zeroed() } }; let mut attrs: Termios = original.into(); From c2376e77de9b79cebdaa05ff0b6f5e5480330d74 Mon Sep 17 00:00:00 2001 From: Andrew Walbran Date: Thu, 7 Dec 2023 15:17:56 +0000 Subject: [PATCH 6/6] Fix clippy warning on illumos. --- src/sys/termios.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sys/termios.rs b/src/sys/termios.rs index dbd75a932b..ccc42cec91 100644 --- a/src/sys/termios.rs +++ b/src/sys/termios.rs @@ -936,6 +936,7 @@ mod test { #[test] fn roundtrip_termios() { // A fake termios including flag bits which we don't recognise. + #[allow(clippy::needless_update)] let original = libc::termios { c_iflag: 0xf00f, c_oflag: 0xd00d,