Skip to content

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.

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

Labels

👀 pr-needs-review PR needs review from a maintainer or community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

top: No longer updates again

4 participants