Skip to content

stty: verify tcsetattr applied all requested settings - #13893

Open
melihemik wants to merge 1 commit into
uutils:mainfrom
melihemik:stty-verify-tcsetattr
Open

stty: verify tcsetattr applied all requested settings#13893
melihemik wants to merge 1 commit into
uutils:mainfrom
melihemik:stty-verify-tcsetattr

Conversation

@melihemik

Copy link
Copy Markdown
Contributor

Fixes #10324

POSIX allows tcsetattr() to return success even when it could only partially apply the requested settings:

The tcsetattr() function shall return successfully if it was able to perform any of the requested actions, even if some of the requested actions could not be performed.

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's eq_mode() covers. Platform-specific fields like line_discipline are left out on purpose because the kernel may normalise them independently of what we wrote.

Error message matches GNU:

standard input: unable to perform all requested operations

Four unit tests cover the new helper: identical structs, one flag differing, a control character differing, and a baud rate differing.

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
@codspeed-hq

codspeed-hq Bot commented Aug 12, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 1.98%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 3 improved benchmarks
❌ 1 regressed benchmark
✅ 343 untouched benchmarks
⏩ 46 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

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)

Open in CodSpeed

Footnotes

  1. 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.

@collinfunk

Copy link
Copy Markdown

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's eq_mode() covers.

/// 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+.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

stty: no verification that tcsetattr applied all settings

2 participants