SchOS/kernel/sys/table.inc
Nexoniarz 6f3175d8a5 flock, fcntl record locks
There were none: fcntl answered F_SETLK with EINVAL and flock was not a
system call. Alpine's apk, which runs unmodified on SchOS through
Alpine's own musl, locks its database before reading it and stopped
there.

kernel/fs/lock.c keeps one table of advisory locks keyed by (dev, inum):
flock() for the whole file, owned by the open file description;
F_SETLK/F_SETLKW/F_GETLK for byte ranges, owned by the process and
released when it closes any descriptor on the file or exits; and the
F_OFD_* forms, ranges owned by the description. flock and record locks
do not see each other, as on Linux. Waiters sleep until any release and
are interrupted by a signal.

cmd/locktest checks each between a parent and a child, including range
splitting, F_GETLK's report, and a blocked waiter being woken.

shell.nix gains pkg-config, meson, ninja, m4, bison, flex and xz, for
the X ports.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
2026-10-24 12:22:36 +02:00

309 lines
11 KiB
SQL

// Segregated Kernel -- central syscall table. ONE line per syscall.
//
// Format: SYSCALL(nr, linux_nr, name)
// nr SchOS native syscall number
// linux_nr Linux x86_64 syscall number, or NO_LINUX if none
// name implemented as sys_<name>() in kernel/sys/sys_*.c
//
// To add a syscall:
// 1. Add ONE line here.
// 2. Write the body with SYSCALL_DEFINE(<name>) in a kernel/sys/sys_*.c.
//
// Everything else is generated from this file: the SYS_* constants
// (include/core/syscall.h), the dispatch table (kernel/sys/syscall.c), and the
// Linux ABI translation map (kernel/sys/linux_abi.c). The Linux number used
// to live in a second hand-maintained table in linux_abi.c; it does not any
// more, so a syscall can no longer be half-registered.
//
// A syscall reachable under more than one Linux number (e.g. stat/newstat)
// gets extra SYSCALL_ALIAS(linux_nr, name) lines.
// --- process ---
SYSCALL( 1, 57, fork)
SYSCALL( 2, 60, exit)
SYSCALL( 3, NO_LINUX, wait)
SYSCALL( 6, 62, kill)
SYSCALL( 7, 59, exec)
SYSCALL( 11, 39, getpid)
SYSCALL( 13, NO_LINUX, sleep)
SYSCALL( 14, NO_LINUX, uptime)
SYSCALL( 29, NO_LINUX, waitpid)
SYSCALL( 30, 112, setsid)
SYSCALL( 31, NO_LINUX, reboot)
SYSCALL( 32, NO_LINUX, shutdown)
SYSCALL( 66, 56, clone)
SYSCALL( 67, 231, exit_group)
SYSCALL( 68, 61, wait4)
SYSCALL( 83, 105, setuid)
SYSCALL( 84, 106, setgid)
SYSCALL( 85, 124, getsid)
SYSCALL( 89, 110, getppid)
SYSCALL( 91, 121, getpgid)
SYSCALL( 94, 186, gettid)
SYSCALL( 92, 109, setpgid)
SYSCALL( 93, 111, getpgrp)
// --- identity ---
SYSCALL( 47, 102, getuid)
SYSCALL( 48, 107, geteuid)
SYSCALL( 69, 104, getgid)
SYSCALL( 70, 108, getegid)
SYSCALL( 71, 95, umask)
// --- memory ---
SYSCALL( 12, NO_LINUX, sbrk)
SYSCALL( 35, 9, mmap)
SYSCALL( 36, 11, munmap)
// Shared memory. These carried NO_LINUX while they were ENOSYS stubs, which
// meant a musl-linked program calling shmget() never reached them at all --
// it got "bad syscall" from the ABI translation rather than an answer. Now
// that they do something, they need the numbers programs actually use.
SYSCALL( 37, 29, shmget)
SYSCALL( 38, 30, shmat)
SYSCALL( 39, 67, shmdt)
SYSCALL( 59, 10, mprotect)
SYSCALL( 74, 12, brk)
// --- filesystem ---
SYSCALL( 4, 22, pipe)
SYSCALL( 5, 0, read)
SYSCALL( 8, 5, fstat)
SYSCALL( 9, 80, chdir)
SYSCALL( 10, 32, dup)
SYSCALL( 15, 2, open)
SYSCALL( 16, 1, write)
SYSCALL( 17, 133, mknod)
SYSCALL( 18, 87, unlink)
SYSCALL( 19, 86, link)
SYSCALL( 20, 83, mkdir)
SYSCALL( 21, 3, close)
SYSCALL( 24, 8, lseek)
SYSCALL( 33, 33, dup2)
SYSCALL( 34, 72, fcntl)
// `delete` -- the recycle bin. It hides a file instead of removing it, so the
// blocks are never freed and a program that deletes a temp file gets no space
// back. Inherited from the third-party filesystem in kernel/fs/fs.c and
// orphaned by the decision to keep only Linux syscall numbering, so nothing
// reaches it. Its effect on read and write has been removed; the entry stays
// only because sys_delete() is still compiled, and both die with fs.c.
SYSCALL( 51, NO_LINUX, delete)
SYSCALL( 52, NO_LINUX, show)
SYSCALL( 53, NO_LINUX, showstat)
SYSCALL( 54, 77, ftruncate)
SYSCALL( 55, 76, truncate)
SYSCALL( 56, 82, rename)
SYSCALL( 57, 88, symlink)
SYSCALL( 58, 89, readlink)
SYSCALL( 61, 79, getcwd)
SYSCALL( 73, 19, readv)
SYSCALL( 72, 20, writev)
SYSCALL( 76, 4, stat)
SYSCALL( 77, 6, lstat)
SYSCALL( 78, 21, access)
SYSCALL( 79, 257, openat)
SYSCALL( 80, 81, fchdir)
SYSCALL( 86, 292, dup3)
SYSCALL( 87, 293, pipe2)
// --- device / I/O ---
SYSCALL( 22, NO_LINUX, vga_sync)
SYSCALL( 23, NO_LINUX, getmouse)
SYSCALL( 45, 23, select)
SYSCALL( 46, 7, poll)
SYSCALL( 60, 16, ioctl)
// --- sockets ---
//
// These carried NO_LINUX while they were ENOSYS stubs, which meant a
// musl-linked program calling socket() never reached them at all -- the ABI
// translation answered "bad syscall" before the stub could answer ENOSYS.
// Now that they do something they need the numbers programs actually use.
//
// `shutdown` is deliberately not the name here: SchOS already has a native
// shutdown() that powers the machine off (syscall 32), and two syscalls
// cannot share a sys_ function name. Linux 48 maps to sockshutdown instead.
SYSCALL( 40, 41, socket)
SYSCALL( 41, 49, bind)
SYSCALL( 42, 50, listen)
SYSCALL( 43, 43, accept)
SYSCALL( 44, 42, connect)
SYSCALL(187, 44, sendto)
SYSCALL(188, 45, recvfrom)
SYSCALL(189, 48, sockshutdown)
SYSCALL(190, 53, socketpair)
SYSCALL(191, 54, setsockopt)
SYSCALL(192, 55, getsockopt)
// accept4() differs from accept() only by a flags argument carrying
// SOCK_CLOEXEC/SOCK_NONBLOCK. It was an alias for accept, which silently
// dropped both -- and it cannot be an alias now that they are honoured: accept
// takes three arguments, so reading a fourth register from an accept() caller
// reads whatever it last left there and invents a flag out of stack litter.
SYSCALL(198, 288, accept4)
// sendmsg/recvmsg exist for the one thing only they can do: carry a descriptor
// from one process to another (SCM_RIGHTS). docs/plan/foundations.md item 1.
SYSCALL(199, 46, sendmsg)
SYSCALL(200, 47, recvmsg)
// memfd_create: an anonymous shared memory object reached by descriptor.
// docs/plan/foundations.md item 2 -- the thing a Wayland buffer crosses on,
// and the reason the descriptor passing above had to exist first.
SYSCALL(201, 319, memfd_create)
// --- time ---
SYSCALL( 28, 37, alarm)
SYSCALL( 49, 96, gettimeofday)
SYSCALL( 50, 35, nanosleep)
SYSCALL( 88, 228, clock_gettime)
// --- signals ---
SYSCALL( 25, NO_LINUX, sigfillset)
SYSCALL( 26, 14, sigprocmask)
SYSCALL( 27, NO_LINUX, sigwait)
SYSCALL( 90, 13, rt_sigaction)
// --- POSIX / Linux-ABI compat ---
SYSCALL( 62, 158, arch_prctl)
SYSCALL( 95, 63, uname)
SYSCALL( 96, 217, getdents64)
SYSCALL( 63, 218, set_tid_address)
SYSCALL( 64, 273, set_robust_list)
SYSCALL( 65, 202, futex)
SYSCALL( 75, 302, prlimit)
SYSCALL( 81, NO_LINUX, enable_linux_abi)
SYSCALL( 82, 97, getrlimit)
// --- signal extensions ---
SYSCALL( 97, 15, rt_sigreturn)
SYSCALL( 98, 131, sigaltstack)
SYSCALL( 99, 127, rt_sigpending)
SYSCALL(100, 128, rt_sigtimedwait)
SYSCALL(101, 130, rt_sigsuspend)
// --- process extensions ---
SYSCALL(102, 157, prctl)
SYSCALL(103, 234, tgkill)
SYSCALL(104, 200, tkill)
SYSCALL(105, 34, pause)
SYSCALL(106, NO_LINUX, getitimer)
SYSCALL(107, NO_LINUX, setitimer)
SYSCALL(108, 98, getrusage)
SYSCALL(109, 100, times)
SYSCALL(110, 99, sysinfo)
SYSCALL(111, 24, sched_yield)
SYSCALL(112, 204, sched_getaffinity)
SYSCALL(113, 203, sched_setaffinity)
SYSCALL(114, 247, waitid)
// --- identity extensions ---
SYSCALL(115, 113, setreuid)
SYSCALL(116, 114, setregid)
SYSCALL(117, 118, getresuid)
SYSCALL(118, 120, getresgid)
SYSCALL(119, 117, setresuid)
SYSCALL(120, 119, setresgid)
SYSCALL(121, 115, getgroups)
SYSCALL(122, 116, setgroups)
SYSCALL(123, 122, setfsuid)
SYSCALL(124, 123, setfsgid)
// --- filesystem extensions ---
SYSCALL(125, 90, chmod)
SYSCALL(126, 91, fchmod)
SYSCALL(127, 92, chown)
SYSCALL(128, 93, fchown)
SYSCALL(129, 94, lchown)
SYSCALL(130, 84, rmdir)
SYSCALL(131, NO_LINUX, fsync)
SYSCALL(132, NO_LINUX, fdatasync)
SYSCALL(133, 162, sync)
SYSCALL(134, 17, pread)
SYSCALL(135, 18, pwrite)
SYSCALL(148, 132, utime)
SYSCALL(149, 235, utimes)
SYSCALL(150, 261, utimensat)
SYSCALL(151, 187, sendfile)
SYSCALL(152, NO_LINUX, preadv2)
SYSCALL(153, NO_LINUX, pwritev2)
SYSCALL(154, 285, fallocate)
SYSCALL(155, 137, statfs)
SYSCALL(156, 138, fstatfs)
SYSCALL(157, 161, chroot)
// --- attributes, and the index over them (SchFS phase 5) ---
//
// Linux's numbers for the xattr calls, so a program that already knows how to
// set an extended attribute needs no changes. schfs_query has no Linux
// equivalent -- it is the one genuinely new call -- so it is native-only.
SYSCALL(193, 188, setxattr)
SYSCALL(194, 191, getxattr)
SYSCALL(195, 197, removexattr)
SYSCALL(196, NO_LINUX, schfs_index)
SYSCALL(197, NO_LINUX, schfs_query)
// --- memory extensions ---
SYSCALL(136, 28, madvise)
SYSCALL(137, NO_LINUX, mremap)
SYSCALL(138, NO_LINUX, msync)
SYSCALL(139, NO_LINUX, mincore)
SYSCALL(140, 149, mlock)
SYSCALL(141, 150, munlock)
SYSCALL(142, 151, mlockall)
SYSCALL(143, 152, munlockall)
SYSCALL(144, 221, fadvise64)
SYSCALL(145, 160, setrlimit)
SYSCALL(146, 140, getpriority)
SYSCALL(147, 141, setpriority)
// --- at-syscalls ---
SYSCALL(158, 258, mkdirat)
SYSCALL(159, 259, mknodat)
SYSCALL(160, 263, unlinkat)
SYSCALL(161, 264, renameat)
SYSCALL(162, 265, linkat)
SYSCALL(163, 266, symlinkat)
SYSCALL(164, 267, readlinkat)
SYSCALL(165, 268, fchmodat)
SYSCALL(166, 269, faccessat)
SYSCALL(167, 262, fstatat)
SYSCALL(168, 260, fchownat)
SYSCALL(169, 316, renameat2)
// --- time extensions ---
SYSCALL(170, 201, time)
SYSCALL(171, 229, clock_getres)
SYSCALL(172, 230, clock_nanosleep)
// --- misc ---
SYSCALL(173, 103, syslog)
SYSCALL(174, 318, getrandom)
SYSCALL(175, 270, pselect6)
SYSCALL(176, 271, ppoll)
// --- epoll / eventfd / signalfd / timerfd ---
// signalfd4 and eventfd2 are 289 and 290. 282 and 284 are the originals,
// which have no flags argument -- they were once aliased to the new ones,
// which then read their flags from whatever the caller left in a register.
SYSCALL(177, 291, epoll_create1)
SYSCALL(178, 233, epoll_ctl)
SYSCALL(179, 232, epoll_wait)
SYSCALL(180, 289, signalfd4)
SYSCALL(181, 290, eventfd2)
SYSCALL(182, 283, timerfd_create)
SYSCALL(183, 286, timerfd_settime)
SYSCALL(184, 287, timerfd_gettime)
SYSCALL(202, 213, epoll_create)
SYSCALL(203, 281, epoll_pwait)
SYSCALL(204, 282, signalfd)
SYSCALL(205, 284, eventfd)
SYSCALL(206, 73, flock)
// --- mounts ---
SYSCALL(185, 165, mount)
SYSCALL(186, 166, umount2)
// --- additional Linux numbers routed to an existing handler ---
SYSCALL_ALIAS( 58, fork)
SYSCALL_ALIAS( 280, utimensat)
SYSCALL_ALIAS( 295, readv)
SYSCALL_ALIAS( 296, writev)