userland.rundocs70Try the demo
Reference

Syscalls

The RISC-V runner implements the Linux RV64 syscall ABI that BusyBox, Node.js and the catalog apps use: 98 syscall numbers have a handler in runners/riscv/src/syscall.rs, a few of them deliberate stubs.

The guest executes ECALL with the syscall number in a7 and arguments in a0–a5; the result goes back in a0. Anything without a handler returns -ENOSYS. Counts on this page come from the dispatch match in nano v0.2.1.

Handling modes

  • Internal: resolved inside the WebAssembly module (memory, threads, sockets, time, signals).
  • FS_PENDING: file-system calls are written to a shared request block and completed by the host's in-memory filesystem; see Host API.
  • Blocking: futex, epoll_pwait, ppoll and timers park the thread; the host resumes it when an event or a virtual-server connection arrives.

Implemented syscalls

Area
Syscalls
Files (FS_PENDING)
openat, close, read, write, readv, writev, pread64, pwrite64, preadv, pwritev, lseek, getdents64, newfstatat, fstat, statx, readlinkat, mkdirat, unlinkat, renameat2, faccessat, utimensat, getcwd, chdir, fcntl, ioctl, dup, dup3, pipe2
Durability (succeed, nothing to flush)
sync, fsync, fdatasync, syncfs
Memory
brk, mmap, mremap, munmap (stub), mprotect (stub), madvise (stub)
Processes and threads
clone, execve, wait4, exit, exit_group, getpid, getppid, gettid, set_tid_address, set_robust_list, futex, sched_yield, sched_getaffinity, prctl, prlimit64, rseq, capget, umask
Identity
getuid, geteuid, getgid, getegid
Signals
rt_sigaction (stub), rt_sigprocmask (stub), rt_sigreturn, sigaltstack, kill, tkill, tgkill
Sockets
socket, socketpair, bind, listen, accept, accept4, connect, sendto, recvfrom, shutdown, getsockname, getpeername, getsockopt, setsockopt
Polling and events
epoll_create1, epoll_ctl, epoll_pwait, ppoll, eventfd2, timerfd_create, timerfd_settime
Time
clock_gettime, clock_getres, nanosleep, times
System
uname, sysinfo, syslog, getrandom, riscv_flush_icache (no-op), io_uring_setup (returns ENOSYS on purpose)

That is 98 numbers. Notable gaps: there is no symlinkat or linkat (so ln -s inside the guest fails), signal handlers are never delivered, and munmap doesn't release memory (the allocators are bump allocators). See Limitations.

See which syscalls an app uses

Every catalog manifest records the syscalls the app used in its conformance run (conformance.syscalls_used). The sample maps them to names.

SDK · JavaScript

Syscalls used by ripgrep

javascript
const names = { 17: "getcwd", 25: "fcntl", 29: "ioctl", 56: "openat", 57: "close", 63: "read", 64: "write", 66: "writev", 73: "ppoll", 79: "newfstatat", 80: "fstat", 94: "exit_group", 96: "set_tid_address", 113: "clock_gettime", 123: "sched_getaffinity", 131: "tgkill", 132: "sigaltstack", 134: "rt_sigaction", 135: "rt_sigprocmask", 160: "uname", 172: "getpid", 174: "getuid", 178: "gettid", 214: "brk", 215: "munmap", 222: "mmap", 226: "mprotect", 233: "madvise", 261: "prlimit64", 278: "getrandom" };
const m = await nano.catalog().manifest("ripgrep");
const used = m.conformance.syscalls_used;
print(`${m.name} ${m.version}: ${used.length} syscalls, tested=${m.conformance.tested}`);
print(used.map((n) => names[n] ?? n).join(" "));
loading…
Expected output
ripgrep 14.1.0: 21 syscalls, tested=true
getcwd fcntl ioctl openat close read ppoll newfstatat fstat exit_group set_tid_address clock_gettime sigaltstack rt_sigaction rt_sigprocmask uname getuid brk munmap mmap getrandom

Each catalog app page lists the app's tier; RISC-V apps use this ABI. The other runners don't: host-engine Node.js calls the kernel bus directly and wasm apps use WASI preview 1 (see Runners & engines).