Sixty-five headers sat side by side in include/, so `#include "irq.h"` said nothing about where irq.h was or what it belonged to, and errno.h, stat.h and fcntl.h at the top shadowed the system's for any host tool built with -I./include. They are in folders now -- arch/ core/ fs/ dev/ gfx/ net/ uapi/ (and ldls/ for the Linux driver layer) -- and every include names the folder, as Linux's do: "core/proc.h". Done mechanically and checked the hard way: the kernel built from this tree disassembles identically to the one built from the tree before it. The full image boots, and userland is the same set of programs. Paths in docs and comments follow; docs/guides/layout.md has a table of what is where, and tools/fix-includes.py rewrites old-style includes from the folders in the tree, for code written before this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
52 lines
2.7 KiB
Markdown
52 lines
2.7 KiB
Markdown
---
|
|
name: schunix-sockets-and-evdev
|
|
description: "Unix domain sockets and /dev/input evdev both work; the one lock rule, the names-not-in-the-VFS tradeoff, and where the syscall numbers went"
|
|
metadata:
|
|
node_type: memory
|
|
type: project
|
|
originSessionId: 9d8a2aef-bcf0-47a0-96c6-f706efab4a95
|
|
modified: 2026-08-05T07:12:20.950Z
|
|
---
|
|
|
|
Unix domain sockets (`kernel/net/unix.c`, `include/net/socket.h`, `kernel/sys/sys_net.c`)
|
|
and raw input events (`kernel/dev/input.c`, `include/dev/input.h`) are both done and
|
|
verified — `tools\bootcheck.ps1 -Sock` and `-Evdev`.
|
|
|
|
**One lock for the whole socket table, deliberately.** A pipe gets a lock per
|
|
pipe because every operation touches one object; a socket operation touches
|
|
two, and per-socket locks need an ordering rule every path obeys or they
|
|
deadlock. Worse, a reader testing `peer_closed` under its own lock while the
|
|
closer sets it under the peer's has no interlock and sleeps through its own
|
|
wakeup. Don't "optimise" this into per-socket locks.
|
|
|
|
**Socket names live in a table, not the filesystem.** `ls -l /tmp/schcom` will
|
|
not show an `s` and `unlink()` of a socket path returns ENOENT. Fixing it
|
|
properly means a new inode type through both filesystems, iget, dirlookup and
|
|
stat — a VFS change, not a socket change. Everything that matters works.
|
|
|
|
`connect()` deliberately does **not** wait for `accept()`. A queued connection
|
|
is already established on Unix; blocking would deadlock any server that
|
|
connects to itself.
|
|
|
|
The syscalls had real Linux numbers assigned (41/49/50/43/42 and friends).
|
|
They were `NO_LINUX` stubs before, which meant a musl program calling
|
|
`socket()` got "bad syscall" from the ABI translation and never reached the
|
|
stub at all — same trap as [[schunix-shm-and-mmap]]. `shutdown` is registered
|
|
as `sockshutdown` because Schunix already has a native `shutdown` that powers
|
|
the machine off.
|
|
|
|
**evdev:** `/dev/input/event0` (keyboard) and `event1` (mouse), major 7, Linux
|
|
`struct input_event` layout. Fed by the PS/2 keyboard, the PS/2 mouse and USB
|
|
HID. The console keeps its own path — both consumers see every key, so keys
|
|
pressed during a test also land on the shell's input line.
|
|
|
|
Two things that are not obvious:
|
|
- Below 0x54 a Linux keycode **is** the AT set-1 scancode, so the PS/2 path
|
|
needs no table. USB HID does need one (`hid_keycode[]`), because HID numbers
|
|
keys by position and the AT set numbers them by matrix wiring order.
|
|
- A full event ring drops the **oldest** event. Dropping the newest is the
|
|
obvious choice and it is wrong: the event most likely lost is a key release,
|
|
and a lost release leaves the key held down forever.
|
|
|
|
See also [[schunix-console-tty]], [[schunix-framebuffer-device]],
|
|
[[schunix-verify-by-driving-shell]].
|