TonicBoxOS · TB32 reference

Syscall reference

Userland reaches the kernel across one boundary: the sys instruction. This is every call it exposes. The prelude wraps the common ones as ordinary functions; everything else you invoke directly with __sys.

Convention. Put the syscall number in r7 and up to six arguments in r1-r6; the result comes back in r1. From TBC that is __sys(num, a, b, c, d, e, f). A negative return is an errno (e.g. -1 EPERM, -2 ENOENT, -9 EBADF, -13 EACCES). Calls marked root require an effective uid of 0. Resolving a path needs search (execute) permission on every directory it descends through, and listing a directory needs read permission on it. Unallocated numbers return -38 ENOSYS. A handful of kernel-internal calls (shell↔kernel handshakes and other plumbing) exist but are intentionally left off this list - if you're poking at those, you're past needing docs.

01Files & filesystem

#callwhat it does
0read(int fd, char* buf, int n)Read up to n bytes into buf, advancing the offset. fd 0 / tty devices read the console. Returns bytes read; -9 if fd is invalid.
78read_nb(int fd, char* buf, int len)The non-blocking counterpart to read: pull up to len bytes of pending console input into buf without ever blocking. Returns the bytes ready now, or 0 if none. Reads the console stdin regardless of fd.
1write(int fd, char* buf, int n)Write n bytes. fd 1/2 go to the console. Returns bytes written; -9 if fd isn't open and writable.
2open(char* path, int flags)Open (or create) a file. Flags: O_WRONLY=1 O_RDWR=2 O_CREAT=0x40 O_TRUNC=0x200 O_APPEND=0x400. Returns an fd; -2/-13/-21/-28.
3close(int fd)Release the fd. Always returns 0.
5stat(char* path, int* out)Fill a 6-word stat: out[0]=mode, [4]=uid, [8]=size, [12]=type (1 file / 2 dir), [16]=gid, [20]=inode. -2 if missing.
7listdir(char* path, char* buf, int cap)Write directory entry names into buf. Returns bytes written; -2/-13/-20.
9getcwd(char* buf, int cap)Copy the working directory into buf. Returns its length.
15unlink(char* path)Delete a regular file. Returns 0; -2/-13/-21.
16mkdir(char* path, int mode)Create a directory (mode masked by the umask). Returns 0; -13/-17/-28.
17rmdir(char* path)Remove an empty directory. Returns 0; -2/-13/-20/-39.
18rename(char* old, char* new)Rename or move an entry, replacing an existing file or empty directory. Returns 0; -2, -13, -22 EINVAL (into its own subtree), -28, -39 ENOTEMPTY (target directory not empty).
19chmod(char* path, int mode)Set permission bits. Owner or root only. Returns 0; -1 EPERM / -2.
23chown(char* path, int uid)Set an entry's owner uid (leaves the gid; clears any setuid/setgid bit). Returns 0; -1 EPERM / -2.
25chdir(char* path)Change the working directory. Returns 0; -2/-20.
29lseek(int fd, int off, int whence)Reposition an fd. whence: 0 SET, 1 CUR, 2 END. Returns the new offset; -9.
85pipe(int fds[2])Create a pipe: fds[0] is the read end, fds[1] the write end. Reading blocks until data or EOF (all writers closed); writing blocks until it fits, and raises SIGPIPE/-32 EPIPE once every reader has closed. Returns 0; -24 EMFILE.
86dup(int oldfd)Duplicate oldfd onto the lowest free fd, sharing the same open file (and offset). Returns the new fd; -9/-24.
87dup2(int oldfd, int newfd)Duplicate oldfd onto newfd (closing newfd first); newfd may be 0/1/2 to redirect stdio onto a file or pipe. Returns newfd; -9.
88symlink(char* target, char* linkpath)Create a symbolic link at linkpath pointing at target. Returns 0; -13/-17/-28.
89readlink(char* path, char* buf, int cap)Read a symlink's target into buf. Returns its length; -2/-22 EINVAL (not a symlink).
90lstat(char* path, void* statbuf)Like stat but does not follow a final symlink (type 3 = symlink). Returns 0; -2.
91link(char* oldpath, char* newpath)Create a hard link newpath to the same inode as oldpath. Returns 0; -1 EPERM (directory) / -13/-17.
47umask(int mask)Set the file-creation mask. Returns the previous mask.
49chowng(char* path, int uid, int gid)Change uid and/or gid (clears any setuid/setgid bit); pass -1 to leave a field alone. Changing uid needs root; changing gid needs root or (owner and group member). -1/-2.

02Processes & exec

#callwhat it does
11exit(int code)Terminate the process with an exit code. Does not return.
22execve(char* path)Replace the current image, keeping credentials; argv0 = path. No return on success; -2/-13. Deliberately single-argument.
24srun(int argc, char** argv)Run one command as a child: a fused fork + exec + wait. Honors setuid/setgid bits. Returns the child's exit code (127 not found, 126 not executable, 1 on error). The shell pipes via fork+pipe+dup2 now, so any stdin-feed / stdout-capture arguments are vestigial.
26set_raw(int on)Toggle raw (unbuffered, no-echo) keystroke input. Returns 0.
46execvp(char* path, char** argv, int argc)PATH-aware execve with an explicit argv vector (so argv0 can differ, e.g. -sh). No return on success; -2/-13.
61fork()Duplicate the process. Returns the child pid to the parent, 0 to the child; -11 EAGAIN if no free slot.
62waitpid(int pid, int* status, int opts)Reap a child (pid -1/0 = any). Writes its code to status. Returns the reaped pid, 0 with WNOHANG (opts bit 0), or -10 ECHILD.
63getpid()Return the process id.
64getppid()Return the parent process id.
65procsnapshot(char* buf, int cap)Write 32-byte records for live processes: [0]=pid, [4]=ppid, [8]=state, [12]=euid, [16..32]=name. Returns the count.
79procsnap2(char* buf, int cap)A richer snapshot (used by htop for CPU%/MEM%/TIME+): buf[0..8] holds clock_ms, then up to cap 48-byte records: [0]=pid, [4]=ppid, [8]=state, [12]=euid, [16]=insns (u64), [24]=start_ms, [28]=mem_bytes, [32..48]=name. Returns the count.

03Users, groups & credentials

#callwhat it does
13getuid()Return the real uid.
14geteuid()Return the effective uid.
30getgid()Return the real gid.
31getegid()Return the effective gid.
32setuid(int uid)Root sets real+effective+saved uid; otherwise only to the real or saved uid. Returns 0 or -1 EPERM.
33setgid(int gid)Same rules as setuid, for the gid. Returns 0 or -1.
35seteuid(int euid)Set the effective uid (to the real/saved uid, or anything if root). -1 otherwise.
36setegid(int egid)Set the effective gid, same rules. -1 otherwise.
37setreuid(int ruid, int euid)Set real and effective uid together; -1 leaves a field. Saved uid follows the effective. -1 EPERM if not root.
38setregid(int rgid, int egid)Set real and effective gid together; -1 leaves a field. -1 EPERM if not root.
39getgroups(int* list, int size)Write up to size supplementary gids into list (size 0 = just count). Returns the number of groups.
40setgroups(int* list, int n)Replace the supplementary groups (up to 16). Returns 0 or -1 EPERM.
48getlogin(char* out, int cap)Copy the session's login name into out and put the login time in r2. Returns the name length.

04Environment

#callwhat it does
41getenv(char* name, char* out, int cap)Copy a variable's value into out. Returns its length, or -1 if unset.
42setenv(char* name, char* val)Set a variable. Returns 0, or -1 if the store is full.
43unsetenv(char* name)Remove a variable. Always returns 0.
44getenviron(char* out, int cap)Copy the packed NAME=VAL\0 environment block into out. Returns its byte length.

05Signals & timers

#callwhat it does
66signal(int sig, int handler)Install a handler: 0 default, 1 ignore, else a function address. Returns the previous handler; -1 for signal 0, out-of-range, KILL, or STOP.
67kill(int pid, int sig)Send a signal (sig 0 = existence check). A negative pid signals process group -pid; pid 0 signals the caller's group. Returns 0; -3 ESRCH / -22 EINVAL.
69sigprocmask(int how, int mask)Adjust the blocked-signal mask. how: 0 BLOCK, 1 UNBLOCK, 2 SET. KILL/STOP are never blockable. Returns the old mask.
70pause()Block until a signal is delivered.
92setpgid(int pid, int pgid)Set a process's group (pid 0 = self, pgid 0 = its own pid). Returns 0; -3.
93getpgid(int pid)Return a process's group id (pid 0 = self).
94setsid()Start a new session; the caller becomes session and group leader. Returns the new session id.
95getsid(int pid)Return a process's session id (pid 0 = self).
96tcsetpgrp(int fd, int pgrp)Set the controlling terminal's foreground process group. Returns 0.
97tcgetpgrp(int fd)Return the controlling terminal's foreground process group.
73msleep(int ms)Sleep for ms milliseconds - real-time pacing for game and event loops. Returns 0 once the interval elapses.
76sleep(int secs)Sleep for secs seconds. Returns 0 if the full time elapsed, else the seconds left unslept (a signal cut it short).
77alarm(int secs)Arm a SIGALRM timer (secs 0 cancels). Returns the seconds remaining on any prior alarm.

06Debugger (ptrace-like)

These back tbdbg and strace. The tracee runs de-privileged in a dedicated memory window. Status codes are 0 exited, 1 breakpoint, 2 step, 3 syscall, 4 fault, 5 blocked, 6 subprocess. All return -1 when there is no active tracee.

#callwhat it does
50dbg_spawn(char* path, char** argv, int argc)Load a fresh tracee, stopped at entry. -1 if already tracing or tracing a setuid-root binary as non-root; -2/-13.
51dbg_step(int* out)Single-step one instruction. out[0..1] = [status, info]. Returns the status.
52dbg_cont(int max, int trace_sys, int* out)Run up to max instructions (0 = 50M); trace_sys traps syscalls. Returns the stop status.
53dbg_regs(int* buf)Write the 16 registers, then pc (word 16) and flags (word 17: Z/N/C/V). Returns pc.
54dbg_setreg(int idx, int val)Set a tracee register (idx 0-15) or pc (idx 16). Returns 0.
55dbg_read(int addr, int len, char* buf)Read tracee memory into buf. Returns bytes read.
56dbg_write(int addr, int len, char* buf)Write buf into tracee memory. Returns bytes written.
57dbg_break(int addr)Set a breakpoint (max 16). Returns 0; -1 if the table is full.
58dbg_unbreak(int addr)Remove a breakpoint. Returns 0.
59dbg_kill()Detach and discard the tracee. Returns 0.
60dbg_statget(int* out)Read the current status/info without stepping. Returns the status.

07System & misc

#callwhat it does
27time()Return the current time in epoch seconds.
80clock_gettime(int clk, void* ts)Write {sec, nsec} to ts. clk 1 MONOTONIC (ms since boot), else REALTIME (epoch). Returns 0.
81gettimeofday(void* tv)Write {sec, usec} (epoch) to tv. Returns 0.
82nanosleep(void* req, void* rem)Sleep for the {sec, nsec} at req (millisecond granularity). Returns 0 once elapsed.
83brk(void* addr)Set the program break (heap top) to addr; brk(0) queries it. Returns 0; -1 if it would collide with the stack.
84sbrk(int delta)Grow the heap by delta bytes and return the previous break (used by malloc); (void*)-1 on overflow.
100mmap(void* addr, int len, int prot, int flags, int fd, int off)Map len bytes and return the mapping address. prot is PROT_READ 1 | PROT_WRITE 2 | PROT_EXEC 4; flags is MAP_FIXED 0x10 | MAP_ANON 0x20. Anonymous maps are demand-zero; file-backed maps populate pages from fd at off and enforce the same read permission as open. A writable MAP_SHARED file map is rejected (-95). -22 EINVAL / -9 EBADF / -12 ENOMEM.
101munmap(void* addr, int len)Unmap a whole prior mapping (frees its frames). Returns 0; -22 EINVAL if addr/len do not match a mapping.
102mprotect(void* addr, int len, int prot)Change the protection of a whole mapping. Returns 0; -22 EINVAL (not a whole mapping) / -13 EACCES (granting write beyond the file's permission).
28getrandom(char* buf, int len)Fill buf with len pseudo-random bytes (userland PRNG). Returns len.
45crypt(char* pw, char* setting, char* out, int cap)Hash pw with the salt from setting, writing a $5$salt$hash string (SHA-crypt style) into out. Returns its length.
71klogread(char* buf, int cap)Drain the kernel log ring into buf (blocks while empty). Returns bytes drained. (syslogd uses this.)
72ioctl(int fd, int req, int arg)Device control. fd 0/1/2 are the console tty (TIOCGWINSZ 0x5413, TCGETS 0x5401). -9 EBADF / -25 ENOTTY.
74mount(char* source, char* target, char* fstype)Mount a filesystem at target. Returns 0; -1/-2/-12/-16/-20.
75umount(char* target)Unmount a filesystem (/ never unmounts). Returns 0; -1/-16/-22.
98reboot()Request a session reboot; the host reseeds the ASLR slide and stack canary and resets the machine to a fresh boot. Returns 0. (The reboot command.)