--- name: schunix-linux-open-flags description: "include/uapi/fcntl.h must hold Linux's open-flag values — the userland is all Linux-ABI, and a mismatch silently corrupts files" metadata: node_type: memory type: project originSessionId: a665e14b-86bd-4b41-a228-51377f3e9225 modified: 2026-08-03T13:59:19.392Z --- **`include/uapi/fcntl.h` holds Linux x86-64 open-flag values, and must keep holding them.** Every program in the userland is built against a libc that sends Linux values; the kernel reads them with these constants. Do not "tidy" them into a neat sequence — they are an external interface. They disagreed until 2026-08-03, and the symptoms looked like filesystem corruption rather than a header mistake: - Linux `O_APPEND` (0x400) landed on Schunix's `O_TRUNC`, so **`cmd >> file` truncated** the file it was supposed to extend. - Linux `O_TRUNC` (0x200) landed on `O_CREATE`, so **`cmd > file` did not truncate** and left whatever was past the new end in place. Found by making `tools/bootcheck.ps1` do ordinary shell work — write a file, append to it, `wc -c` the result — instead of only booting to a prompt. The byte count was the only thing that said which failure had happened. See [[schunix-verify-by-driving-shell]]. Two related traps fixed at the same time, both worth re-checking after any syscall work: - `sys_openat` silently dropped `O_TRUNC` and `O_APPEND` while `sys_open` honoured both, so the same redirection behaved differently depending on which entry point libc called. **Any flag handled in one must be handled in both.** - `rmdir` was `NO_LINUX` in `kernel/sys/table.inc`, so every Linux-ABI program got ENOSYS. A syscall with no Linux number is unreachable from userland — see [[schunix-syscall-single-table]].