{{ message }}
Repository navigation
devpts: return immediately from a MIN=0 TIME=0 read with no input - #16089
Open
karthik1729 wants to merge 1 commit into
Open
karthik1729 wants to merge 1 commit into
karthik1729 wants to merge 1 commit into
Conversation
In non-canonical mode with VMIN=0 and VTIME=0, POSIX has read(2) return whatever input is available at once, which is zero bytes when there is none. The replica read path ignored VMIN and VTIME and returned ErrWouldBlock, so a blocking reader waited forever. btop turns canonical mode off with VMIN=0 and VTIME=0 and then reads stdin in a loop until read returns 0. After the first key or mouse event its second read blocked, and its drawing thread waited on the main thread for good, so the screen stopped updating. Programs that poll input this way hang the same way. Return 0 from inputQueueRead for that termios setting when the queue is empty, and keep blocking when VMIN is non-zero.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

A read from the replica side of a pty with VMIN=0 and VTIME=0 (non-canonical mode) blocks when there is no input. POSIX says it must return 0 bytes at once. gVisor's
inputQueueReadignores VMIN and VTIME and returnsErrWouldBlock, so a blocking reader waits forever.Impact. btop sets
c_cc[VMIN] = 0andc_cc[VTIME] = 0when it turns canonical mode off, then reads stdin withwhile ((count = read(STDIN_FILENO, buf, sizeof(buf))) > 0). After the first key or mouse event it reads again and that second read never returns. Its drawing thread waits on the main thread, so the screen stops updating and the program has to be killed. Any program that polls input this way hangs the same way. A pty opened inside the sandbox is affected. A terminal that comes from the host (for examplekubectl exec -it) is not.Reproduce. In a container running under runsc, on a pty created inside the sandbox (for example with
script):On Linux
returnedprints at once. Under runsc it never prints.Change. In
inputQueueRead, whenICANONis off and bothVMINandVTIMEare 0, return 0 bytes instead ofErrWouldBlockwhen the queue is empty. A non-zeroVMINstill blocks.VTIMEwith a timeout is still not implemented and is left alone.Testing.
devpts_test.go: the polling read returns 0 and still returns input that is available, andMIN=1still returnsErrWouldBlock. I could not run Bazel here, so I have not run these two tests.runscand the containerd shim from thegobranch (release-20260817.0 plus 26 commits) with this change, on three nodes (kernel 6.17, nested virtualization). btop on a pty created inside the sandbox kept drawing through a single mouse event, a mouse-motion burst and an arrow-key burst. The same source without the change froze on the first event in each run.