-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
stty: Improve option handling and align behavior with GNU coreutils #9255
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Add GNU-compatible parsing of colon-separated hex -g output - Restore termios from saved state before applying new settings - Preserve platform-dependent fields while validating input robustly
- Replace Box<dyn UError> with USimpleError for stty helpers and save-format parsing to reduce indirection and simplify error handling - Use as_str/copied for argument iteration and convert flag bits via into() for clearer, more idiomatic Rust and improved type safety
- Update missing/invalid argument helpers to return Box<dyn UError> for consistent error typing - Propagate errors with map_err(Into::into) at call sites to match new helper signatures - Simplify string handling (String::as_str, &**s) to reduce verbosity and clarify intent
- Return USimpleError directly from missing_arg/invalid_* helpers to avoid Box indirection - Replace redundant map_err(Into::into) uses with direct missing_arg calls for clarity - Aligns error handling with UResult expectations and improves readability
- Fix mis-indented else branch to ensure missing_arg is called correctly - Improve readability and maintain consistent control flow structure
- Cast parsed hex flag values to u64 to match bitflag expectations - Remove redundant conversions when constructing termios flag sets - Ensures proper handling of saved formats on platforms with 64-bit flags
- Use parse_hex_u32 return type directly for flag bitfields - Simplifies code by eliminating unnecessary u32-to-u64 conversions
- Cast parsed flag bit values into appropriate integer types - Prevent potential type mismatch or incorrect flag interpretation during restore
- Use tcflag_t-based parser for hex flag values to match termios types - Avoid extra casts when reconstructing Input/Output/Control/Local flags for correctness and clarity
- Add tcflag, bitflag, and lflags to spell-checker ignore list - Prevent false positives when working with recently added flag names
- Add "cflags" to spell-checker ignore hints in stty.rs - Prevent false positives during spell-checking for terminal flag names
- Treat unknown dash-prefixed arguments as invalid options to match GNU stty behavior - Treat unrecognized bare words as missing arguments for clearer error reporting
- Treat unrecognized options starting with '-' as invalid arguments - Treat unrecognized bare words as invalid arguments instead of missing - Match project test expectations and clarify the inline documentation
|
GNU testsuite comparison: |
CodSpeed Performance ReportMerging #9255 will not alter performanceComparing Summary
Footnotes
|
|
GNU testsuite comparison: |
src/uu/stty/src/stty.rs
Outdated
|
|
||
| // Obtain the original termios and overwrite specific fields on top of it to preserve | ||
| // platform-dependent fields. | ||
| let mut termios = tcgetattr(std::io::stdout().as_fd()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is is assuming that we're opening stdout, but no, it should be the device: tcgetattr(opts.file.as_fd()).
So, I think that this function should be instead moved at later point after all the args have been parsed, and it should take a &Termios, not returning it once it has been opened in the same way it's done currently
| // combination setting | ||
| } else if let Some(combo) = string_to_combo(arg) { | ||
| valid_args.append(&mut combo_to_flags(combo)); | ||
| } else if arg.starts_with('-') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mhlhl, this implies that doing stty foo bar would pass, until we fail parsing... While to me we should just fail as GNU does in that case with stty: invalid argument 'foo'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. Let's do that.
Reuse base termios struct from target device to avoid redundant tcgetattr calls, improve performance, and ensure correctness in parse_save_format by cloning the base instead of hardcoding stdout. Also add GNU stty-compatible error handling for invalid save format with colons.
src/uu/stty/src/stty.rs
Outdated
| restored_from_save = Some(termios); | ||
| settings_iter = Box::new(rest.iter().copied()); | ||
| } | ||
| // GNU stty は先頭が save 形式っぽいのにパースできなければ即エラーにする |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
???
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry fix
- Updated error handling comment to describe GNU stty behavior more clearly for English readers. - Translated comment on termios cloning to explain preservation of platform-specific fields.
|
GNU testsuite comparison: |
src/uu/stty/src/stty.rs
Outdated
| } | ||
|
|
||
| // Fetch termios for the target device once and reuse it downstream | ||
| let base_termios = tcgetattr(opts.file.as_fd())?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO this can be still just an Option set to None here, and you set it when needed, so before parsing, or - if unset - before applying the arguments.
src/uu/stty/src/stty.rs
Outdated
|
|
||
| /// GNU stty -g compatibility: restore Termios from the colon-separated hexadecimal representation | ||
| /// produced by print_in_save_format. | ||
| fn parse_save_format(s: &str, base: &Termios) -> Result<Termios, Box<dyn UError>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you just clone before passing and avoid returning it?
…rmance - Delay the initial tcgetattr call until termios is actually needed, using a closure that caches the result. - Modify parse_save_format to mutate the passed termios in-place instead of returning a clone, reducing unnecessary copies and improving efficiency.
|
GNU testsuite comparison: |
Summary:
Details:
Rationale:
Scope / Impact:
Testing:
#9056