diff --git a/Cargo.lock b/Cargo.lock index 0c2952ebd3..03c18702d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4118,7 +4118,7 @@ dependencies = [ "cfg_aliases", "clap", "fluent", - "nix", + "libc", "rustix", "uucore", ] diff --git a/src/uu/stty/Cargo.toml b/src/uu/stty/Cargo.toml index ad87872136..da06eb9da2 100644 --- a/src/uu/stty/Cargo.toml +++ b/src/uu/stty/Cargo.toml @@ -18,7 +18,7 @@ doctest = false [target.'cfg(unix)'.dependencies] clap = { workspace = true } fluent = { workspace = true } -nix = { workspace = true, features = ["ioctl", "term"] } +libc = { workspace = true } rustix = { workspace = true, features = ["fs", "termios"] } uucore = { workspace = true, features = ["parser"] } diff --git a/src/uu/stty/src/flags.rs b/src/uu/stty/src/flags.rs index d25936628d..794bfef29c 100644 --- a/src/uu/stty/src/flags.rs +++ b/src/uu/stty/src/flags.rs @@ -10,14 +10,12 @@ // spell-checker:ignore lnext rprnt susp swtch vdiscard veof veol verase vintr vkill vlnext vquit vreprint vstart vstop vsusp vswtc vwerase werase // spell-checker:ignore sigquit sigtstp // spell-checker:ignore cbreak decctlq evenp litout oddp +// spell-checker:ignore VDSUSP VMIN VSTATUS VTIME VSWTCH use crate::Flag; -#[cfg(not(bsd))] -use nix::sys::termios::BaudRate; -use nix::sys::termios::{ - ControlFlags as C, InputFlags as I, LocalFlags as L, OutputFlags as O, - SpecialCharacterIndices as S, +use rustix::termios::{ + ControlModes as C, InputModes as I, LocalModes as L, OutputModes as O, SpecialCodeIndex as S, }; #[derive(Debug)] @@ -31,10 +29,7 @@ pub enum BaudType { #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] pub enum AllFlags<'a> { - #[cfg(bsd)] Baud(u32, BaudType), - #[cfg(not(bsd))] - Baud(BaudRate, BaudType), ControlFlags((&'a Flag, bool)), InputFlags((&'a Flag, bool)), LocalFlags((&'a Flag, bool)), @@ -84,6 +79,14 @@ pub const INPUT_FLAGS: &[Flag] = &[ Flag::new("iutf8", I::IUTF8), ]; +// workaround for unexposed const of OutputModes +#[allow(unused_macros)] +macro_rules! o { + ($val:expr) => { + O::from_bits_retain($val as _) + }; +} + pub const OUTPUT_FLAGS: &[Flag] = &[ Flag::new("opost", O::OPOST).sane(), #[cfg(any( @@ -103,49 +106,49 @@ pub const OUTPUT_FLAGS: &[Flag] = &[ target_os = "haiku", target_os = "linux" ))] - Flag::new("ofdel", O::OFDEL), + Flag::new("ofdel", o!(libc::OFDEL)), #[cfg(any( target_vendor = "apple", target_os = "android", target_os = "haiku", target_os = "linux" ))] - Flag::new_grouped("nl0", O::NL0, O::NLDLY).sane(), + Flag::new_grouped("nl0", o!(libc::NL0), o!(libc::NLDLY)).sane(), #[cfg(any( target_vendor = "apple", target_os = "android", target_os = "haiku", target_os = "linux" ))] - Flag::new_grouped("nl1", O::NL1, O::NLDLY), + Flag::new_grouped("nl1", o!(libc::NL1), o!(libc::NLDLY)), #[cfg(any( target_vendor = "apple", target_os = "android", target_os = "haiku", target_os = "linux" ))] - Flag::new_grouped("cr0", O::CR0, O::CRDLY).sane(), + Flag::new_grouped("cr0", o!(libc::CR0), o!(libc::CRDLY)).sane(), #[cfg(any( target_vendor = "apple", target_os = "android", target_os = "haiku", target_os = "linux" ))] - Flag::new_grouped("cr1", O::CR1, O::CRDLY), + Flag::new_grouped("cr1", o!(libc::CR1), o!(libc::CRDLY)), #[cfg(any( target_vendor = "apple", target_os = "android", target_os = "haiku", target_os = "linux" ))] - Flag::new_grouped("cr2", O::CR2, O::CRDLY), + Flag::new_grouped("cr2", o!(libc::CR2), o!(libc::CRDLY)), #[cfg(any( target_vendor = "apple", target_os = "android", target_os = "haiku", target_os = "linux" ))] - Flag::new_grouped("cr3", O::CR3, O::CRDLY), + Flag::new_grouped("cr3", o!(libc::CR3), o!(libc::CRDLY)), #[cfg(any( target_vendor = "apple", target_os = "android", @@ -159,63 +162,63 @@ pub const OUTPUT_FLAGS: &[Flag] = &[ target_os = "haiku", target_os = "linux" ))] - Flag::new_grouped("tab1", O::TAB1, O::TABDLY), + Flag::new_grouped("tab1", o!(libc::TAB1), O::TABDLY), #[cfg(any( target_vendor = "apple", target_os = "android", target_os = "haiku", target_os = "linux" ))] - Flag::new_grouped("tab2", O::TAB2, O::TABDLY), + Flag::new_grouped("tab2", o!(libc::TAB2), O::TABDLY), #[cfg(any( target_vendor = "apple", target_os = "android", target_os = "haiku", target_os = "linux" ))] - Flag::new_grouped("tab3", O::TAB3, O::TABDLY), + Flag::new_grouped("tab3", o!(libc::TAB3), o!(libc::BSDLY)), #[cfg(any( target_vendor = "apple", target_os = "android", target_os = "haiku", target_os = "linux" ))] - Flag::new_grouped("bs0", O::BS0, O::BSDLY).sane(), + Flag::new_grouped("bs0", o!(libc::BS0), o!(libc::BSDLY)).sane(), #[cfg(any( target_vendor = "apple", target_os = "android", target_os = "haiku", target_os = "linux" ))] - Flag::new_grouped("bs1", O::BS1, O::BSDLY), + Flag::new_grouped("bs1", o!(libc::BS1), o!(libc::BSDLY)), #[cfg(any( target_vendor = "apple", target_os = "android", target_os = "haiku", target_os = "linux" ))] - Flag::new_grouped("vt0", O::VT0, O::VTDLY).sane(), + Flag::new_grouped("vt0", o!(libc::VT0), o!(libc::VTDLY)).sane(), #[cfg(any( target_vendor = "apple", target_os = "android", target_os = "haiku", target_os = "linux" ))] - Flag::new_grouped("vt1", O::VT1, O::VTDLY), + Flag::new_grouped("vt1", o!(libc::VT1), o!(libc::VTDLY)), #[cfg(any( target_vendor = "apple", target_os = "android", target_os = "haiku", target_os = "linux" ))] - Flag::new_grouped("ff0", O::FF0, O::FFDLY).sane(), + Flag::new_grouped("ff0", o!(libc::FF0), o!(libc::FFDLY)).sane(), #[cfg(any( target_vendor = "apple", target_os = "android", target_os = "haiku", target_os = "linux" ))] - Flag::new_grouped("ff1", O::FF1, O::FFDLY), + Flag::new_grouped("ff1", o!(libc::FF1), o!(libc::FFDLY)), ]; pub const LOCAL_FLAGS: &[Flag] = &[ @@ -249,77 +252,6 @@ pub const LOCAL_FLAGS: &[Flag] = &[ Flag::new("extproc", L::EXTPROC), ]; -// BSD's use u32 as baud rate, so using the enum is unnecessary. -#[cfg(not(bsd))] -pub const BAUD_RATES: &[(&str, BaudRate)] = &[ - ("0", BaudRate::B0), - ("50", BaudRate::B50), - ("75", BaudRate::B75), - ("110", BaudRate::B110), - ("134", BaudRate::B134), - ("150", BaudRate::B150), - ("200", BaudRate::B200), - ("300", BaudRate::B300), - ("600", BaudRate::B600), - ("1200", BaudRate::B1200), - ("1800", BaudRate::B1800), - ("2400", BaudRate::B2400), - ("4800", BaudRate::B4800), - ("9600", BaudRate::B9600), - ("19200", BaudRate::B19200), - ("38400", BaudRate::B38400), - ("57600", BaudRate::B57600), - ("115200", BaudRate::B115200), - ("230400", BaudRate::B230400), - // TODO: https://github.com/nix-rust/nix/pull/2815 - #[cfg(not(any( - target_os = "cygwin", - target_os = "fuchsia", - target_os = "hurd", - target_os = "redox" - )))] - ("460800", BaudRate::B460800), - #[cfg(any(target_os = "android", target_os = "linux"))] - ("500000", BaudRate::B500000), - #[cfg(any(target_os = "android", target_os = "linux"))] - ("576000", BaudRate::B576000), - // TODO: https://github.com/nix-rust/nix/pull/2815 - #[cfg(not(any( - target_os = "cygwin", - target_os = "fuchsia", - target_os = "hurd", - target_os = "redox" - )))] - ("921600", BaudRate::B921600), - #[cfg(any(target_os = "android", target_os = "linux"))] - ("1000000", BaudRate::B1000000), - #[cfg(any(target_os = "android", target_os = "linux"))] - ("1152000", BaudRate::B1152000), - #[cfg(any(target_os = "android", target_os = "linux"))] - ("1500000", BaudRate::B1500000), - #[cfg(any(target_os = "android", target_os = "linux"))] - ("2000000", BaudRate::B2000000), - #[cfg(any( - target_os = "android", - all(target_os = "linux", not(target_arch = "sparc64")) - ))] - ("2500000", BaudRate::B2500000), - #[cfg(any( - target_os = "android", - all(target_os = "linux", not(target_arch = "sparc64")) - ))] - ("3000000", BaudRate::B3000000), - #[cfg(any( - target_os = "android", - all(target_os = "linux", not(target_arch = "sparc64")) - ))] - ("3500000", BaudRate::B3500000), - #[cfg(any( - target_os = "android", - all(target_os = "linux", not(target_arch = "sparc64")) - ))] - ("4000000", BaudRate::B4000000), -]; /// Control characters for the stty command. /// /// This constant provides a mapping between the names of control characters @@ -378,3 +310,58 @@ pub const COMBINATION_SETTINGS: &[(&str, bool)] = &[ ("sane", false), ("tabs", true), ]; + +// rustix::termios::SpecialCodeIndex, but ordered as same as C header +#[cfg(bsd)] // different order with Linux +pub const SPECIAL_INDICES: &[S] = &[ + S::VEOF, + S::VEOL, + S::VEOL2, + S::VERASE, + S::VWERASE, + S::VKILL, + S::VREPRINT, + S::VINTR, + S::VQUIT, + S::VSUSP, + S::VDSUSP, + S::VSTART, + S::VSTOP, + S::VLNEXT, + S::VDISCARD, + S::VMIN, + S::VTIME, + S::VSTATUS, +]; + +#[cfg(not(bsd))] +pub const SPECIAL_INDICES: &[S] = &[ + S::VINTR, + S::VQUIT, + S::VERASE, + S::VKILL, + S::VEOF, + S::VTIME, + S::VMIN, + #[cfg(not(any(target_os = "haiku", target_os = "hurd")))] + S::VSWTC, + S::VSTART, + S::VSTOP, + S::VSUSP, + S::VEOL, + #[cfg(not(target_os = "haiku"))] + S::VREPRINT, + #[cfg(not(target_os = "haiku"))] + S::VDISCARD, + #[cfg(not(target_os = "haiku"))] + S::VWERASE, + #[cfg(not(target_os = "haiku"))] + S::VLNEXT, + S::VEOL2, + #[cfg(target_os = "haiku")] + S::VSWTCH, + #[cfg(target_os = "hurd")] + S::VDSUSP, + #[cfg(any(target_os = "hurd", target_os = "illumos"))] + S::VSTATUS, +]; diff --git a/src/uu/stty/src/stty.rs b/src/uu/stty/src/stty.rs index 90a211c296..8aa05fb254 100644 --- a/src/uu/stty/src/stty.rs +++ b/src/uu/stty/src/stty.rs @@ -19,14 +19,14 @@ mod flags; use crate::flags::AllFlags; -use crate::flags::COMBINATION_SETTINGS; +use crate::flags::{COMBINATION_SETTINGS, SPECIAL_INDICES}; use clap::{Arg, ArgAction, ArgMatches, Command}; -use nix::sys::termios::{ - ControlFlags, InputFlags, LocalFlags, OutputFlags, SetArg, SpecialCharacterIndices as S, - Termios, cfsetispeed, cfsetospeed, tcgetattr, tcsetattr, +use rustix::termios::{ + ControlModes as ControlFlags, InputModes as InputFlags, LocalModes as LocalFlags, + OptionalActions, OutputModes as OutputFlags, SpecialCodeIndex as S, Termios, Winsize, + tcgetattr, tcgetwinsize, tcsetattr, tcsetwinsize, }; -use rustix::termios::{Winsize, tcgetwinsize, tcsetwinsize}; use std::cmp::Ordering; use std::fs::File; use std::io::{self, Stdin, stdin, stdout}; @@ -38,8 +38,6 @@ use uucore::format_usage; use uucore::parser::num_parser::ExtendedParser; use uucore::translate; -#[cfg(not(bsd))] -use flags::BAUD_RATES; use flags::{CONTROL_CHARS, CONTROL_FLAGS, INPUT_FLAGS, LOCAL_FLAGS, OUTPUT_FLAGS}; const ASCII_DEL: u8 = 127; @@ -238,7 +236,7 @@ fn stty(opts: &Options) -> UResult<()> { )); } - let mut set_arg = SetArg::TCSADRAIN; + let mut set_arg = OptionalActions::Drain; let mut valid_args: Vec = Vec::new(); if let Some(args) = &opts.settings { @@ -321,10 +319,10 @@ fn stty(opts: &Options) -> UResult<()> { } } "drain" => { - set_arg = SetArg::TCSADRAIN; + set_arg = OptionalActions::Drain; } "-drain" => { - set_arg = SetArg::TCSANOW; + set_arg = OptionalActions::Now; } "size" => { valid_args.push(ArgOptions::Print(PrintSetting::Size)); @@ -386,8 +384,9 @@ fn stty(opts: &Options) -> UResult<()> { } } - let mut termios = - tcgetattr(opts.file.as_fd()).map_err_context(|| opts.device_name.clone())?; + let mut termios = tcgetattr(&opts.file) + .map_err(io::Error::from) + .map_err_context(|| opts.device_name.clone())?; // iterate over valid_args, match on the arg type, do the matching apply function for arg in &valid_args { @@ -405,9 +404,11 @@ fn stty(opts: &Options) -> UResult<()> { } } } - tcsetattr(opts.file.as_fd(), set_arg, &termios)?; + tcsetattr(&opts.file, set_arg, &termios).map_err(io::Error::from)?; } else { - let termios = tcgetattr(opts.file.as_fd()).map_err_context(|| opts.device_name.clone())?; + let termios = tcgetattr(&opts.file) + .map_err(io::Error::from) + .map_err_context(|| opts.device_name.clone())?; print_settings(&termios, opts)?; } Ok(()) @@ -481,7 +482,7 @@ fn parse_rows_cols(arg: &str) -> Option { /// Parse a saved terminal state string in stty format. /// /// The format is colon-separated hexadecimal values: -/// `input_flags:output_flags:control_flags:local_flags:cc0:cc1:cc2:...` +/// `input_modes:output_modes:control_modes:local_modes:cc0:cc1:cc2:...` /// /// - Must have exactly 4 + NCCS parts (4 flags + platform-specific control characters) /// - All parts must be non-empty valid hex values @@ -489,7 +490,7 @@ fn parse_rows_cols(arg: &str) -> Option { /// - Returns `None` if format is invalid fn parse_saved_state(arg: &str) -> Option> { let parts: Vec<&str> = arg.split(':').collect(); - let expected_parts = 4 + nix::libc::NCCS; + let expected_parts = 4 + libc::NCCS; // GNU requires exactly the right number of parts for this platform if parts.len() != expected_parts { @@ -595,9 +596,7 @@ fn print_terminal_size( window_size: Option<&Winsize>, term_size: Option<&Winsize>, ) -> io::Result<()> { - // GNU linked against glibc 2.42 provides us baudrate 51 which panics cfgetospeed - // so we repeat syscall... use termios.output_speed() instead if we switched to rustix instead. - let speed = rustix::termios::tcgetattr(&opts.file)?.output_speed(); + let speed = termios.output_speed(); let mut printer = WrappedPrinter::new(window_size); printer.print(&translate!("stty-output-speed", "speed" => speed)); if opts.all { @@ -612,8 +611,6 @@ fn print_terminal_size( let line = termios.line_discipline; printer.print(&translate!("stty-output-line", "line" => line)); } - #[cfg(not(any(target_os = "linux", target_os = "redox")))] - let _ = termios; // remove this hack when we switched to rustix completely printer.flush(); Ok(()) } @@ -696,19 +693,7 @@ fn string_to_baud(arg: &str, baud_type: flags::BaudType) -> Option> let normalized = normalized.strip_suffix('.').unwrap_or(normalized); let value = parse_baud_with_rounding(normalized)?; - // BSDs use a u32 for the baud rate, so any decimal number applies. - #[cfg(bsd)] - return Some(AllFlags::Baud(value, baud_type)); - - #[cfg(not(bsd))] - { - for (text, baud_rate) in BAUD_RATES { - if text.parse::().ok() == Some(value) { - return Some(AllFlags::Baud(*baud_rate, baud_type)); - } - } - None - } + Some(AllFlags::Baud(value, baud_type)) } /// return `Some(flag)` if the input is a valid flag, `None` if not @@ -731,7 +716,7 @@ fn string_to_flag(option: &str) -> Option> { None } -fn control_char_to_string(cc: nix::libc::cc_t) -> nix::Result { +fn control_char_to_string(cc: u8) -> io::Result { let (meta_prefix, code) = match cc { 0 => return Ok(translate!("stty-output-undef")), 0x80.. => ("M-", cc - 0x80), @@ -747,22 +732,22 @@ fn control_char_to_string(cc: nix::libc::cc_t) -> nix::Result { // DEL character 0x7f => Ok(("^", '?')), // Out of range (above 8 bits) - _ => Err(nix::errno::Errno::ERANGE), + _ => Err(rustix::io::Errno::RANGE), }?; Ok(format!("{meta_prefix}{ctrl_prefix}{character}")) } -fn print_control_chars( +fn print_control_modes( termios: &Termios, opts: &Options, term_size: Option<&Winsize>, -) -> nix::Result<()> { +) -> io::Result<()> { if !opts.all { // Print only control chars that differ from sane defaults let mut printer = WrappedPrinter::new(term_size); for (text, cc_index) in CONTROL_CHARS { - let current_val = termios.control_chars[*cc_index as usize]; + let current_val = termios.special_codes[*cc_index]; let sane_val = get_sane_control_char(*cc_index); if current_val != sane_val { @@ -780,12 +765,12 @@ fn print_control_chars( for (text, cc_index) in CONTROL_CHARS { printer.print(&format!( "{text} = {};", - control_char_to_string(termios.control_chars[*cc_index as usize])? + control_char_to_string(termios.special_codes[*cc_index])? )); } printer.print(&translate!("stty-output-min-time", - "min" => termios.control_chars[S::VMIN as usize], - "time" => termios.control_chars[S::VTIME as usize] + "min" => termios.special_codes[S::VMIN], + "time" => termios.special_codes[S::VTIME] )); printer.flush(); Ok(()) @@ -794,14 +779,18 @@ fn print_control_chars( fn print_in_save_format(termios: &Termios) { print!( "{:x}:{:x}:{:x}:{:x}", - termios.input_flags.bits(), - termios.output_flags.bits(), - termios.control_flags.bits(), - termios.local_flags.bits() + termios.input_modes.bits(), + termios.output_modes.bits(), + termios.control_modes.bits(), + termios.local_modes.bits() ); - for cc in termios.control_chars { + for &i in SPECIAL_INDICES { + let cc = termios.special_codes[i]; print!(":{cc:x}"); } + for _ in SPECIAL_INDICES.len()..libc::NCCS { + print!(":0"); + } println!(); } @@ -823,7 +812,7 @@ fn print_settings(termios: &Termios, opts: &Options) -> io::Result<()> { }; print_terminal_size(termios, opts, window_size.as_ref(), term_size.as_ref())?; - print_control_chars(termios, opts, window_size.as_ref())?; + print_control_modes(termios, opts, window_size.as_ref())?; print_flags(termios, opts, CONTROL_FLAGS, window_size.as_ref()); print_flags(termios, opts, INPUT_FLAGS, window_size.as_ref()); print_flags(termios, opts, OUTPUT_FLAGS, window_size.as_ref()); @@ -867,7 +856,7 @@ fn print_flags( } /// Apply a single setting -fn apply_setting(termios: &mut Termios, setting: &AllFlags) -> nix::Result<()> { +fn apply_setting(termios: &mut Termios, setting: &AllFlags) -> io::Result<()> { match setting { AllFlags::Baud(_, _) => apply_baud_rate_flag(termios, setting)?, AllFlags::ControlFlags((setting, disable)) => { @@ -886,22 +875,19 @@ fn apply_setting(termios: &mut Termios, setting: &AllFlags) -> nix::Result<()> { Ok(()) } -fn apply_baud_rate_flag(termios: &mut Termios, input: &AllFlags) -> nix::Result<()> { +fn apply_baud_rate_flag(termios: &mut Termios, input: &AllFlags) -> io::Result<()> { if let AllFlags::Baud(rate, baud_type) = input { match baud_type { - flags::BaudType::Input => cfsetispeed(termios, *rate)?, - flags::BaudType::Output => cfsetospeed(termios, *rate)?, - flags::BaudType::Both => { - cfsetispeed(termios, *rate)?; - cfsetospeed(termios, *rate)?; - } + flags::BaudType::Input => termios.set_input_speed(*rate)?, + flags::BaudType::Output => termios.set_output_speed(*rate)?, + flags::BaudType::Both => termios.set_speed(*rate)?, } } Ok(()) } fn apply_char_mapping(termios: &mut Termios, mapping: &(S, u8)) { - termios.control_chars[mapping.0 as usize] = mapping.1; + termios.special_codes[mapping.0] = mapping.1; } /// Apply a saved terminal state to the current termios. @@ -922,14 +908,13 @@ fn apply_saved_state(termios: &mut Termios, state: &[u32]) { }; // Apply the four flag groups, done (as _) for MacOS size compatibility - termios.input_flags = InputFlags::from_bits_truncate(*s0 as _); - termios.output_flags = OutputFlags::from_bits_truncate(*s1 as _); - termios.control_flags = ControlFlags::from_bits_truncate(*s2 as _); - termios.local_flags = LocalFlags::from_bits_truncate(*s3 as _); - - // Apply control characters if present (stored as u32 but used as u8) - for (c, &cc_val) in termios.control_chars.iter_mut().zip(rest) { - *c = cc_val as u8; + termios.input_modes = InputFlags::from_bits_truncate(*s0 as _); + termios.output_modes = OutputFlags::from_bits_truncate(*s1 as _); + termios.control_modes = ControlFlags::from_bits_truncate(*s2 as _); + termios.local_modes = LocalFlags::from_bits_truncate(*s3 as _); + // Apply control characters if present (stored as usize but used as u8) + for (&index, &cc_val) in SPECIAL_INDICES.iter().zip(rest) { + termios.special_codes[index] = cc_val as u8; } } @@ -1135,45 +1120,45 @@ pub fn uu_app() -> Command { impl TermiosFlag for ControlFlags { fn is_in(&self, termios: &Termios, group: Option) -> bool { - termios.control_flags.contains(*self) - && group.is_none_or(|g| !termios.control_flags.intersects(g - *self)) + termios.control_modes.contains(*self) + && group.is_none_or(|g| !termios.control_modes.intersects(g - *self)) } fn apply(&self, termios: &mut Termios, val: bool) { - termios.control_flags.set(*self, val); + termios.control_modes.set(*self, val); } } impl TermiosFlag for InputFlags { fn is_in(&self, termios: &Termios, group: Option) -> bool { - termios.input_flags.contains(*self) - && group.is_none_or(|g| !termios.input_flags.intersects(g - *self)) + termios.input_modes.contains(*self) + && group.is_none_or(|g| !termios.input_modes.intersects(g - *self)) } fn apply(&self, termios: &mut Termios, val: bool) { - termios.input_flags.set(*self, val); + termios.input_modes.set(*self, val); } } impl TermiosFlag for OutputFlags { fn is_in(&self, termios: &Termios, group: Option) -> bool { - termios.output_flags.contains(*self) - && group.is_none_or(|g| !termios.output_flags.intersects(g - *self)) + termios.output_modes.contains(*self) + && group.is_none_or(|g| !termios.output_modes.intersects(g - *self)) } fn apply(&self, termios: &mut Termios, val: bool) { - termios.output_flags.set(*self, val); + termios.output_modes.set(*self, val); } } impl TermiosFlag for LocalFlags { fn is_in(&self, termios: &Termios, group: Option) -> bool { - termios.local_flags.contains(*self) - && group.is_none_or(|g| !termios.local_flags.intersects(g - *self)) + termios.local_modes.contains(*self) + && group.is_none_or(|g| !termios.local_modes.intersects(g - *self)) } fn apply(&self, termios: &mut Termios, val: bool) { - termios.local_flags.set(*self, val); + termios.local_modes.set(*self, val); } } @@ -1298,6 +1283,8 @@ mod tests { // Tests for string_to_baud #[test] fn test_string_to_baud_valid() { + #[cfg(any(target_os = "linux", target_os = "android"))] + assert!(string_to_baud("995", flags::BaudType::Both).is_some()); #[cfg(not(bsd))] { assert!(string_to_baud("9600", flags::BaudType::Both).is_some()); @@ -1319,7 +1306,6 @@ mod tests { fn test_string_to_baud_invalid() { #[cfg(not(bsd))] { - assert_eq!(string_to_baud("995", flags::BaudType::Both), None); assert_eq!(string_to_baud("invalid", flags::BaudType::Both), None); assert_eq!(string_to_baud("", flags::BaudType::Both), None); assert_eq!(string_to_baud("abc", flags::BaudType::Both), None); diff --git a/tests/by-util/test_stty.rs b/tests/by-util/test_stty.rs index 157758db90..b338bcb8ea 100644 --- a/tests/by-util/test_stty.rs +++ b/tests/by-util/test_stty.rs @@ -155,6 +155,8 @@ fn invalid_setting() { fn invalid_baud_setting() { #[cfg(not(any( target_vendor = "apple", + target_os = "android", + target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd", @@ -182,6 +184,8 @@ fn invalid_baud_setting() { #[cfg(not(any( target_vendor = "apple", + target_os = "android", + target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd", @@ -194,6 +198,8 @@ fn invalid_baud_setting() { #[cfg(not(any( target_vendor = "apple", + target_os = "android", + target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd", @@ -1471,10 +1477,12 @@ fn invalid_baud_rate() { .fails() .stderr_contains("invalid ispeed"); - // On non-BSD systems, test invalid numeric baud rate - // On BSD systems, any u32 is accepted, so we skip this test + // On Linux and BSD, any u32 is accepted, so we skip this test + // On other systems, test invalid numeric baud rate #[cfg(not(any( target_vendor = "apple", + target_os = "android", + target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd", diff --git a/util/build-gnu.sh b/util/build-gnu.sh index c3a75b3048..9e5d37d684 100755 --- a/util/build-gnu.sh +++ b/util/build-gnu.sh @@ -156,6 +156,12 @@ else echo "strip t${i}.sh from Makefile and tests/local.mk" sed -i -e "s/\$(tf)\/t${i}.sh//g" Makefile tests/local.mk done + # This intercepts C-function which does not use any syscall. + # GNU supports any baud only on newer glibc and this test is useful if and only if + # we ensure GNU stty 51 fails on legacy glibc using newer glibc. + # But we use ioctl directly to support any baud independently on glibc's version. + # So there is nothing we want to test at here. + sed -i '/tests\/stty\/bad-speed.sh/ D' Makefile # Remove LD_PRELOAD implementation of no-mtab-status-masked-proc. not compatible with our binary sed -i '/tests\/df\/no-mtab-status.sh/ D' Makefile # Remove tests checking for --version & --help