Skip to content

top: Fix refresh hangs by correctly configuring non-blocking TTY#26428

Merged
spholz merged 1 commit intoSerenityOS:masterfrom
NoobZang:top
Jan 23, 2026
Merged

top: Fix refresh hangs by correctly configuring non-blocking TTY#26428
spholz merged 1 commit intoSerenityOS:masterfrom
NoobZang:top

Conversation

@NoobZang
Copy link
Contributor

Setting O_NONBLOCK via fcntl is not sufficient for TTYs in non-canonical mode. A subsequent tcsetattr call would override this, as the default VMIN and VTIME settings cause the driver to block.

Explicitly set VMIN and VTIME to ensure a true non-blocking read.

Fixes #26166.

@github-actions github-actions bot added the 👀 pr-needs-review PR needs review from a maintainer or community member label Nov 25, 2025
@nico
Copy link
Contributor

nico commented Nov 25, 2025

Do you know what caused the regression?

@NoobZang
Copy link
Contributor Author

I hadn't dug into the history. Top code seems good. I guess a deeper change of IO/TTY/fcntl/tcsetattr caused the regression. Explicitly setting VMIN and VTIME makes top more robust.

@spholz
Copy link
Member

spholz commented Dec 3, 2025

I bisected this to 96675e6.

VMIN is by default 1:

#define CMIN 1

(This also matches behavior with other unixes, e.g. OpenBSD: https://github.com/openbsd/src/blob/cfc59e797c2eed7e722f5fc0f94f22ef692897c1/sys/sys/ttydefaults.h#L65. glibc's version is very similar and actually has a BSD license header.)

Though I'm confused why this affects reading from stdin. VMIN and VTIME seem to about reading: http://unixwiz.net/techtips/termios-vmin-vtime.html. And we also only set those values for stdout. So why does this fix the bug?

@stale
Copy link

stale bot commented Dec 24, 2025

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions!

@stale stale bot added the stale label Dec 24, 2025
@oskar-skog
Copy link
Contributor

Though I'm confused why this affects reading from stdin. VMIN and VTIME seem to about reading: http://unixwiz.net/techtips/termios-vmin-vtime.html. And we also only set those values for stdout. So why does this fix the bug?

In normal use, both stdin and stdout are connected to the same file: the terminal. So I think that's how it's working.

@stale stale bot removed the stale label Dec 30, 2025
@spholz
Copy link
Member

spholz commented Dec 30, 2025

Yeah, but I think it would still be better to set it for stdin.

Setting O_NONBLOCK via fcntl is not sufficient for TTYs in
non-canonical mode. A subsequent tcsetattr call would override this,
as the default VMIN and VTIME settings cause the driver to block.

Explicitly set VMIN and VTIME to 0 to ensure a true non-blocking read.

Also, apply these TTY settings to STDIN_FILENO instead of STDOUT_FILENO.
This is semantically more correct as we are configuring input behavior.

Fixes SerenityOS#26166.
@NoobZang
Copy link
Contributor Author

NoobZang commented Jan 2, 2026

I found swapping the fcntl and tcsetattr call order works without setting VMIN=0 (because fcntl sets it back to non-blocking), but I think explicitly setting VMIN=0 and VTIME=0 is safer and less brittle.

I've also moved the config to STDIN_FILENO.

Copy link
Member

@spholz spholz left a comment

Choose a reason for hiding this comment

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

Sorry that it took so long for me to come back to this!

@spholz spholz merged commit 1e69af3 into SerenityOS:master Jan 23, 2026
14 checks passed
@github-actions github-actions bot removed the 👀 pr-needs-review PR needs review from a maintainer or community member label Jan 23, 2026
@NoobZang NoobZang deleted the top branch January 24, 2026 01:42
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.

top: No longer updates again

4 participants