tty: arrow keys, backspace, and four terminals nobody was home on

Three things, all in the first minute of using a shell.

**Arrow keys corrupted the two keystrokes after them.** They arrive as single
keycodes -- KEY_UP is 0xE2 -- and were pushed into the input buffer exactly
like that. No terminal works that way, and 0xE2 is the worst possible byte to
have chosen: it is a UTF-8 lead byte for a three-byte character, so a reader
decoding UTF-8 swallowed the next two keys waiting for continuations that never
arrived. consoleintr() sends the DEC/xterm sequences now -- ESC[A, ESC[D,
ESC[5~ and the rest -- which every terminfo entry and every line editor already
knows. Not echoed: in canonical mode echoing them would move the cursor for
real, which was the other half of what "weird glitches" looked like.

**Then the end of the line vanished as you typed into it**, with the buffer
perfectly correct. One line in vt_putc(): backspace erased the cell it moved
onto. That is a line-discipline erase, not the BS control character -- a
program rubbing a character out sends `\b \b`, and the separation matters
because programs also use plain `\b` to go back. zsh does, on every mid-line
edit:

    echo alpha  \b\b  zha  \b\b

back two, rewrite the tail, back two again to park the cursor. Against a
destructive backspace that last pair deleted the `ha` it had just drawn.

`\b` moves and nothing else now, 0x7f is ignored as on a real terminal, and
consputc() spells its own erase out as `\b \b` as it already did for serial.
ESC[@, ESC[P and ESC[X went in alongside, because TERM=linux declares them.

**VT3 to VT6 were blank** because nothing ran on them. NVT is 6 and the kernel
made all six; only two had a shell, so Alt+F3 switched to a terminal that was
working perfectly and had nobody to talk to. Four more manifests.

Six shells starting at once is enough concurrency to expose an intermittent
fault in one of them -- one boot in five, a wild jump into .data that runs
until it writes to 0, which nothing catches because SchOS never sets EFER.NXE.
Three boots with two shells, none. Recorded rather than fixed: it is not caused
by the manifests, only made likelier by them.

Also: QEMU_NET forwards host 8080/8081/8000 to guest 80/8080/8000, so the httpd
is reachable from the machine running QEMU instead of being sealed behind NAT.
Verified end to end. And the greeting prints once again -- a replaced
supervisor was announcing a boot that had already happened.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ7Qx8E1q1M1bbCq8QLHS2
This commit is contained in:
Nexoniarz 2026-09-14 22:43:54 +02:00
commit ff7afa746e
9 changed files with 317 additions and 8 deletions

View file

@ -0,0 +1,29 @@
# An interactive shell on /dev/tty3.
#
# NVT is 6 (include/vt.h) and the kernel creates all six terminals, but only
# two ever had anything running on them -- so Alt+F3 switched to a terminal
# that was working perfectly and had nobody to talk to, which looks exactly
# like a broken one.
#
# Identical to tty2-shell apart from the number. Six manifests rather than one
# with a range, because schinit has no notion of a template and inventing one
# for six lines each is the wrong trade.
Label = os.schos.tty3-shell
Program = /bin/zsh
Args = -zsh
RunAtLoad = yes
KeepAlive = yes
Environment = TERM=linux
Environment = PATH=/bin:/usr/bin
Environment = HOME=/root
Environment = SHELL=/bin/zsh
ControllingTerminal = yes
StandardIn = /dev/tty3
StandardOut = /dev/tty3
StandardError = /dev/tty3
ThrottleInterval = 1