/** * 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_SYSCALL_OPS_SUSV4_REFS, 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) { const opsDetail = BARE_OS_SYSCALL_OPS_DETAIL_FULL.map((o) => { const refs = BARE_OS_SYSCALL_OPS_SUSV4_REFS[o.name] return refs ? { ...o, susv4Refs: [...refs] } : { ...o } }) return { schemaVersion: 11, 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, posixXsh: { schema: 3, note: 'POSIX.1 XSH-style names: logical names in opsDetail; schema 11 adds susv4Refs tokens (Issue 7 index) on mapped operations. Schema 10: posix_fadvise simulated no-op. Socket family: ENOSYS without BARE_OS_POSIX_SOCKET_FD_BRIDGE. readv/writev: partial posix-pipe facades. nanosleep / clock_gettime via ctx.bareOsSyscall. sendmsg/recvmsg: socketMsgSurface schema 6 (iovecSemantics + recvmsg susv4Refs); optional SCM_RIGHTS logical dup.', namesCsv: bareOsPosixXshOpsCsv() }, socketMsgSurface: { schema: 6, iovecSemantics: { sendmsg: 'bounded_flatten_all_iovs_into_single_wire_payload (see BARE_OS_POSIX_SOCKET_* caps)', recvmsg: 'first_iov_primary_datagram_buffer_partial_ok_remainder_truncated (XSH/recvmsg partial read alignment)', susv4Refs: ['XSH/sendmsg', 'XSH/recvmsg'] }, ancillaryControl: { supported: false, errno: 'ENOTSUP', rejectKeys: [ 'cmsgs', 'control', 'controllen', 'msgHdr.control', 'msgHdr.cmsgs' ], note: 'Binary/kernel ancillary buffers remain ENOTSUP. When BARE_OS_POSIX_SOCKET_SCM_RIGHTS=1, only JSON-shaped `{ fds: number[] }` entries in cmsgs/msgHdr.cmsgs are accepted (see logicalScmRightsOnSend). Schema 5 documents SOCK_STREAM sendmsg parity with SOCK_DGRAM (logical dup on connected TCP bridge fds).' }, logicalScmRightsOnSend: { env: 'BARE_OS_POSIX_SOCKET_SCM_RIGHTS', maxFdsEnv: 'BARE_OS_POSIX_SOCKET_SCM_RIGHTS_MAX_FDS', parseModule: 'bare-os-socket-scm-rights.js', syscallResultField: 'scmRightsLocalDup', note: 'Logical duplication of guest logical fds into new integer fds (same bridge slot / pipe target). Not host SCM_RIGHTS across a kernel boundary. recvmsg still reports controllen 0 — rights are returned on the sendmsg result only.' }, sendmsg: { bridgePartial: true, defaultErrno: 'ENOTSUP', note: 'With BARE_OS_POSIX_SOCKET_FD_BRIDGE, sendmsg flattens bounded iovs; ancillary per ancillaryControl + logicalScmRightsOnSend.' }, recvmsg: { bridgePartial: true, defaultErrno: 'ENOTSUP', susv4Refs: ['XSH/recvmsg'], note: 'recvmsg returns buf + msgHdr.name from peer/rinfo; controllen 0 (no queued ancillary on receive path).' } }, 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: 9, 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 (/run/bare-os/ipc/*): blocking until push or AbortSignal (AbortError); backlog bounded via BARE_OS_IPC_MAX_BYTES' ], 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() } }