stty: verify tcsetattr applied all requested settings - #13893
Conversation
POSIX says tcsetattr() may return success even when it could only partially apply the requested settings. GNU stty reads back the terminal state with tcgetattr() after every write and exits with an error if what the kernel stored differs from what was asked for. We now do the same. The new termios_eq() helper compares the four flag groups (input/output/control/local), all control characters, and both baud rates – the same fields GNU's eq_mode() checks. Platform- specific fields such as line_discipline are intentionally excluded because the kernel may normalise them independently. Fixes uutils#10324
Merging this PR will degrade performance by 1.98%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Simulation | df_with_path |
573.7 µs | 704.7 µs | -18.59% |
| ⚡ | Simulation | du_summarize_balanced_tree[(5, 4, 10)] |
16.8 ms | 16 ms | +4.77% |
| ⚡ | Simulation | du_max_depth_balanced_tree[(6, 4, 10)] |
65.2 ms | 62.5 ms | +4.33% |
| ⚡ | Simulation | complex_relative_date |
330.2 µs | 318.4 µs | +3.72% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing melihemik:stty-verify-tcsetattr (f612337) with main (822aa83)
Footnotes
-
46 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
/// Compare two `Termios` structs for equality the same way GNU's `eq_mode()` does:
/// input/output/control/local flags, all control characters, and both baud rates.
/// We deliberately skip any platform-specific fields (like `line_discipline`) that
/// the kernel may normalise on its own.
fn termios_eq(a: &Termios, b: &Termios) -> bool {
a.input_flags == b.input_flags
&& a.output_flags == b.output_flags
&& a.control_flags == b.control_flags
&& a.local_flags == b.local_flags
&& a.control_chars == b.control_chars
&& cfgetispeed(a) == cfgetispeed(b)
&& cfgetospeed(a) == cfgetospeed(b)
}Please license your contributions under GPLv3+. |
Fixes #10324
POSIX allows
tcsetattr()to return success even when it could only partially apply the requested settings:GNU stty handles this by calling
tcgetattr()after every write and comparing the result to what was requested. If they differ it exits non-zero. We did not do this at all.The fix adds
termios_eq()which checks the four flag groups (input/output/control/local), all control characters, and both baud rates — the same fields GNU'seq_mode()covers. Platform-specific fields likeline_disciplineare left out on purpose because the kernel may normalise them independently of what we wrote.Error message matches GNU:
Four unit tests cover the new helper: identical structs, one flag differing, a control character differing, and a baud rate differing.