Skip to content

stty: clear previous values when setting grouped flags - #15240

Open
ozenyunus35 wants to merge 3 commits into
uutils:mainfrom
ozenyunus35:fix/stty-grouped-flags
Open

ozenyunus35 wants to merge 3 commits into
uutils:mainfrom
ozenyunus35:fix/stty-grouped-flags

Conversation

@ozenyunus35

Copy link
Copy Markdown
Contributor

Summary

Fixes #11963.

Fix stty settings that represent mutually exclusive values within the same bit field.

Previously, applying a new grouped setting only ORed its bits into the existing terminal flags. The previous value was not cleared, so some settings were silently ignored or produced invalid combinations.

For example:

  • Switching from cs8 to cs7 could leave cs8 active.
  • Zero-valued settings such as cs5 and tab0 could not replace an existing value.
  • Applying tab1 followed by tab2 could produce an invalid combined value.

Changes

Update apply_setting to clear the relevant group's existing bits before applying the new value.

The change covers character-size and terminal delay settings, including the grouped settings used by evenp and oddp.

Add two integration tests using a real pseudo-terminal to verify that grouped values replace one another correctly.

Testing

Regression tests:

  • Both new integration tests fail before the fix.
  • Both pass after the fix.

Validation:

  • test_stty: 53 passed, 32 ignored.
  • uu_stty unit tests: 26 passed.
  • cargo fmt --check: passed.
  • Clippy with -D warnings: passed.
  • CSpell: passed.

The tests were run on macOS. Cross-platform behavior will also be covered by CI.

One intermittent test failure occurred during parallel validation, but it could not be reproduced in 30 subsequent runs.

Compatibility

This change intentionally updates grouped flag handling to match the expected GNU stty behavior.

No unrelated command behavior is changed.

AI Assistance

AI assistance was used during implementation and testing. The changes were reviewed and validated before submission.

Settings such as cs5-cs8, nl0/nl1, crN, tabN, bsN, vtN and ffN select
one value of a multi-bit field. They were applied by setting their bits
on top of the current value, so the field was never cleared: `cs7` on a
terminal in `cs8` was ignored, `cs5`/`tab0` (value 0) were no-ops and
`tab2` after `tab1` produced a mix of both. This also affected the
combination settings that use them, such as `evenp`, `oddp` and `sane`.

Clear the field before setting the selected value.

Fixes uutils#11963
@github-actions

Copy link
Copy Markdown

GNU testsuite comparison:

Skipping an intermittent issue tests/date/resolution (passes in this run but fails in the 'main' branch)

Linux pseudo-terminals always keep cs8, so the integration test for the
CSIZE group failed there. Check that group in a unit test that applies
the settings to a termios value instead, and keep the pseudo-terminal
test for the TABDLY group.
Comment thread src/uu/stty/src/stty.rs Outdated
fn apply_flag<T: TermiosFlag>(termios: &mut Termios, setting: &Flag<T>, val: bool) {
// A grouped flag selects one value of a multi-bit field (e.g. `cs7` in CSIZE),
// so the bits of the previously selected value have to be cleared first.
if let (Some(group), true) = (setting.group, val) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could be if val && let Some(group) = setting.group, easier to read, no?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to the let chain in 220b7fe, thanks.

@codspeed

codspeed Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Merging this PR will degrade performance by 20.37%

⚠️ 118 benchmarks spent significant time in system calls

System calls cannot be consistently instrumented, so they are not included in the measure, which understates the real cost. Please switch to the Walltime instrument to accurately measure system calls.

Measurement and system calls

ℹ️ 1 benchmark has no flame graph

The flamegraph could not be generated because too much time was spent in runtime internals, making the visualization not useful for performance analysis.

⚠️ 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

❌ 2 regressed benchmarks
✅ 399 untouched benchmarks
⏩ 54 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ Simulation three_39_bit_primes 490.4 ms 672 ms -27.02%
❌ Simulation five_38_bit_primes 1.7 s 1.9 s -13.11%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing ozenyunus35:fix/stty-grouped-flags (220b7fe) with main (efca981)2

Open in CodSpeed

Footnotes

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

  2. No successful run was found on main (d43f2b8) during the generation of this report, so efca981 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩

This branch has not been deployed

No deployments
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: setting a grouped control flag (e.g. cs7) does not clear existing group bits first

2 participants