/** * JSON payload for `/proc/bare_os/syscalls.json` (single source for tests + vfs provider). */ import { BARE_OS_POSIX_PROFILE_ID, BARE_OS_POSIX_PROFILE_VERSION } from 'bare-os-protocol/bare-os-posix-profile.js' import { BARE_OS_SYSCALL_OPS_DETAIL_FULL, BARE_OS_STOCK_SYSCALL_OPS, bareOsPosixXshOpsCsv } from './bare-os-syscall-ops.js' import { BARE_OS_POSIX_SIGNAL_NAMES } from './bare-os-posix-signals.js' import { bareOsErrnoTableForProc } from './bare-os-posix-errno.js' /** * @param {{ ctxApiVersion: string }} p */ export function buildBareOsSyscallsProcJson(p) { return { schemaVersion: 8, ctxApiVersion: p.ctxApiVersion, posixProfile: { id: BARE_OS_POSIX_PROFILE_ID, version: BARE_OS_POSIX_PROFILE_VERSION, utilitiesIndexPath: '/etc/bare-os/posix_utilities.json' }, ops: [...BARE_OS_STOCK_SYSCALL_OPS], opsDetail: [...BARE_OS_SYSCALL_OPS_DETAIL_FULL], posixXsh: { schema: 2, note: 'POSIX.1 XSH-style names: logical names in opsDetail; socket family are ctx.bareOsSyscall ops returning ENOSYS-shaped results (not kernel socket FDs) unless BARE_OS_POSIX_SOCKET_FD_BRIDGE. readv/writev are partial posix-pipe facades. getsockopt/setsockopt: ENOSYS without bridge fd; with bridge, partial SO_KEEPALIVE/TCP_NODELAY on logical fds. nanosleep-shaped delay via ctx.bareOsSyscall("nanosleep"). SOCK_DGRAM bridge supports passive bind(2), optional connect(2) after bind, send/sendmsg/recv/recvfrom/recvmsg with bounded queue (BARE_OS_POSIX_DGRAM_RECVQ_MAX); bound-without-connect send requires port+host syscall args. sendmsg/recvmsg: non-empty ancillary control is ENOTSUP (schema 3); BARE_OS_POSIX_SOCKET_SCM_RIGHTS reserved for future bare-ipc logical-fd pass-through.', namesCsv: bareOsPosixXshOpsCsv() }, socketMsgSurface: { schema: 3, ancillaryControl: { supported: false, errno: 'ENOTSUP', rejectKeys: [ 'cmsgs', 'control', 'controllen', 'msgHdr.control', 'msgHdr.cmsgs' ], note: 'Normative ENOTSUP before send when non-empty ancillary fields are present (binary control / controllen / non-SCM cmsgs) unless BARE_OS_POSIX_SOCKET_SCM_RIGHTS=1: then cmsgs/msgHdr.cmsgs may list only `{ fds: number[] }` SCM_RIGHTS-shaped objects (cap BARE_OS_POSIX_SOCKET_SCM_RIGHTS_MAX_FDS, default 4). sendmsg returns `scmRightsLocalDup: [{ from, to }]` for duplicated logical fds; recvmsg controllen stays 0. Unset env: ENOTSUP for any non-empty cmsgs without SCM flag.' }, sendmsg: { bridgePartial: true, defaultErrno: 'ENOTSUP', note: 'With BARE_OS_POSIX_SOCKET_FD_BRIDGE and SOCK_DGRAM, sendmsg flattens bounded iovs into one datagram; non-empty ancillary CMSGS rejected with ENOTSUP + ancillaryReject (schema 3).' }, recvmsg: { bridgePartial: true, defaultErrno: 'ENOTSUP', note: 'With bridge + SOCK_DGRAM, recvmsg returns buf + msgHdr.name from rinfo; SCM_RIGHTS / scatter iov / ancillary recv ENOTSUP-shaped (controllen 0).' } }, errnoHints: bareOsErrnoTableForProc(), fdModel: { schema: 1, note: 'Integer FDs index logical VFS/IPC targets in the guest; not host kernel file descriptors.', stdio: [0, 1, 2], register: 'ctx.bareOsRegisterLogicalFd', processTablePath: '/proc/bare_os/process_table.json', processTableSchema: 7, posixLike: { schema: 1, note: 'POSIX open/read/write/close/pipe/dup/fcntl analogs; see docs/architecture/POSIX_DECLARED_PROFILE.md.', open: { mapsTo: ['vfs.readFile', 'vfs.writeFile', 'vfs.exists', 'vfs.lstat'], fds: 'stdio 0–2 reserved; extras via ctx.bareOsRegisterLogicalFd' }, read: { mapsTo: ['vfs.readFile', 'bareOsBinReadStdin', 'IPC fifo consumer'], partial: true }, write: { mapsTo: ['vfs.writeFile', 'console.log / bareOsBinWrite', 'IPC fifo producer'], partial: true }, close: { mapsTo: ['logical fd table eviction', 'IPC channel teardown'], partial: true }, pipe: { mapsTo: ['mkfifo + /run/bare-os/ipc/* in-memory queues'], notOnHyperdrive: true }, mq: { mapsTo: [ 'ctx.bareOsSyscall("mq_open"|"mq_send"|"mq_receive")', 'bareOsIpc POSIX-like named queues (priority sort; bounded maxmsg/maxBytes)' ], partial: true }, dup: { mapsTo: ['ctx.bareOsRegisterLogicalFd copy of target string'], partial: true }, dup2: { mapsTo: ['shell redirect table (2>&1)'], partial: true }, fcntl: { mapsTo: [ 'ctx.bareOsSyscall("fcntl")', 'F_GETFL', 'F_SETFL', 'F_GETLK', 'F_SETLK', 'F_SETLKW', 'cooperative advisory locks per absolute path (or fd→path); session-scoped', 'optional F_SETLKW blocking wait when BARE_OS_POSIX_FCNTL_BLOCKING_WAIT (cap BARE_OS_FCNTL_LOCK_WAIT_MS_MAX)', 'waiters wake FIFO on unlock; no host deadlock detection; starvation possible under heavy writer churn', 'O_APPEND 0x400', 'O_NONBLOCK 0x800', 'bareOsLogicalFdFlags per fd string key' ], partial: true }, poll: { mapsTo: [ 'ctx.bareOsPosixPoll', 'ctx.bareOsPosixPollProbe', 'ctx.bareOsSyscall("posixPoll")' ], partial: true }, socketFamily: { mapsTo: [ 'ctx.bareOsSyscall("socket"|"bind"|"listen"|"accept"|"connect"|"send"|"recv"|"recvfrom"|"shutdown")', 'BARE_OS_POSIX_SOCKET_FD_BRIDGE=1: SOCK_STREAM connect via bareTcp.Socket; passive SOCK_STREAM bind+listen+accept via bareTcp.Server (accepted fds use TCP recv queue + poll/select); SOCK_DGRAM connect+send+recv+recvfrom via bareDgram (UDX); BARE_OS_POSIX_ACCEPT_QUEUE_MAX caps pending accepts' ], notKernelSockets: true } } }, signalModel: { schema: 1, note: 'ctx.bareOsSendSignal delivers to synthetic pids 1–3; ctx.bareOsSigaction may set IGNORE; see process_table.sigactionSurface.', names: [...BARE_OS_POSIX_SIGNAL_NAMES] }, caps: { note: 'VFS path classes and boot policy may deny individual ops at runtime.' }, errnoAlignment: { schema: 1, note: 'errnoHints use Linux/x86-64-style integers (same family as libuv / Holepunch bare-fs binding errors). Logical FD simulation uses EBADF, EAGAIN, EINVAL, ENOSYS, EOPNOTSUPP consistently with bare-os-posix-errno.js.', openFlagsNote: 'fcntl O_APPEND (0x400) and O_NONBLOCK (0x800) match the masks used by bare-fs open flags on the host when translating to guest logical FDs.' }, atMs: Date.now() } }