dev: read /dev/zero and /dev/urandom from them, not from the keyboard

consoleinit() put consoleread/consolewrite in devsw[1], over memread and
memwrite. Major 1 holds the whole mem major (null, zero, full, random,
urandom) and memread already sends the console's minors to the console,
so the override only broke the others: a read of /dev/zero waited for a
typed line. dd and head on either device hung, and `head -c 10 /dev/zero`
only finished because it swallowed the next command.

The console now installs just its open and close hooks. /dev/keyboard
writes are discarded, as consolewrite used to do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
Nexoniarz 2026-10-23 09:33:08 +02:00
commit d90a72e6d3
3 changed files with 15 additions and 2 deletions

View file

@ -355,6 +355,14 @@ from the cycle counter on each byte so two readers do not continue one
sequence. What changed is the property that made it dangerous rather than sequence. What changed is the property that made it dangerous rather than
merely poor. merely poor.
**For a long time it could not be read at all**, and neither could `/dev/zero`.
Both are minors of major 1, and `devsw[1]` is `memread`/`memwrite`, which hand
the console's minors to the console and the rest to their own functions. But
`consoleinit()` installed `consoleread` over the whole major, so a read of
`/dev/zero` waited for a line from the keyboard. `head -c 10 /dev/zero`
"worked" by taking the next command typed. The console now installs only its
`open` and `close` hooks.
## What it does not do ## What it does not do
- **It is a flat list, not a device tree.** There is no parent/child nesting, - **It is a flat list, not a device tree.** There is no parent/child nesting,

View file

@ -820,8 +820,12 @@ consoleinit(void)
initlock(&cons.lock, "console"); initlock(&cons.lock, "console");
initlock(&input_lock, "input"); initlock(&input_lock, "input");
devsw[CONSOLE].write = consolewrite; // Not read and write. Major 1 is the whole mem major -- null, zero, full,
devsw[CONSOLE].read = consoleread; // random, urandom as well as the console and the ttys -- and devsw[1] is
// memread/memwrite, which send the console's minors here and the rest
// where they belong. Installing consoleread over it made /dev/zero and
// /dev/urandom wait for a line from the keyboard, which is why neither
// had ever seemed to work.
devsw[CONSOLE].open = consoleopen; devsw[CONSOLE].open = consoleopen;
devsw[CONSOLE].close = consoleclose; devsw[CONSOLE].close = consoleclose;
cons.locking = 1; cons.locking = 1;

View file

@ -170,6 +170,7 @@ memwrite(struct inode *ip, uint64 off, char *dst, int n)
case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 10: case 11: case 12: case 13: case 14: case 15: case 16:
return consolewrite(ip, off, dst, n); return consolewrite(ip, off, dst, n);
case 7: return fullwrite(ip, off, dst, n); // /dev/full: always ENOSPC case 7: return fullwrite(ip, off, dst, n); // /dev/full: always ENOSPC
case 3: // /dev/keyboard: discarded
case 2: case 2:
case 5: case 5:
case 8: case 8: