Linux System Calls Reference

Common Linux syscalls with number, signature, errno and man-page reference.

Searchable Linux x86-64 system call reference covering process, file, memory, network and signal syscalls with their syscall number, C signature, return value and category. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

Are these syscall numbers the same on every architecture?

No. The numbers shown are for x86-64 (the values in the rax register). Other architectures such as ARM64, x86 (32-bit) and RISC-V use different syscall numbers, though the names and semantics are largely shared. Always check the per-arch table for portable code.

Linux system calls, the kernel boundary

Every time a program reads a file, allocates memory, spawns a process or opens a socket, it crosses from user space into the kernel through a system call. On x86-64, the syscall number goes in the rax register, arguments in rdi, rsi, rdx, r10, r8, r9, and the syscall instruction transfers control to the kernel. This reference lists the most common syscalls with their number, C signature and category so you can decode an strace log or write inline assembly without leaving the page.

How it works

A syscall is dispatched by number. The kernel’s syscall table maps rax to a handler, the handler runs in kernel mode, and the result comes back in rax. At the raw level a return value in the range -4095 to -1 is a negated errno — the glibc wrapper detects this, returns -1 and sets errno to the positive code. Successful calls return a non-negative value: a count of bytes, a new file descriptor, a pointer (from mmap), or 0.

Syscalls group into families. Process calls (fork, clone, execve, exit_group, wait4) manage the process lifecycle. File calls (open/openat, read, write, close, lseek, stat) move data through file descriptors. Memory calls (mmap, munmap, mprotect, brk) manage the address space. Network calls (socket, bind, listen, accept, connect, sendto, recvfrom) drive sockets. Signal calls (kill, rt_sigaction, rt_sigprocmask) deliver and handle asynchronous notifications.

Frequently used syscalls with context

File I/O

openat(dirfd, pathname, flags, mode) — Open a file relative to a directory file descriptor. The *at variant is preferred over open because it avoids TOCTOU races when the directory might change between path resolution and the open. flags include O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_NONBLOCK, O_CLOEXEC. Returns a new file descriptor or -1.

read(fd, buf, count) — Read up to count bytes from fd into buf. Returns the number of bytes actually read, which may be less than count (a short read). A return of 0 means end-of-file. EINTR means a signal arrived — restart the loop.

write(fd, buf, count) — Write count bytes from buf to fd. Returns bytes written, which may be less than count on a non-blocking descriptor or a full kernel buffer. Always loop until all bytes are written.

close(fd) — Releases the file descriptor. Always check the return value — on network file systems a flush error appears here, not in the last write.

Process lifecycle

clone(flags, stack, ...) — The underlying primitive for both threads and processes. Pass CLONE_VM | CLONE_FILES | CLONE_SIGHAND (and others) to share resources as a thread; pass 0 to copy everything as a process. fork() is essentially clone(SIGCHLD, 0).

execve(pathname, argv[], envp[]) — Replace the current process image with a new program. The PID is preserved; the address space, signal handlers, and file descriptors (except those with O_CLOEXEC) carry over.

wait4(pid, wstatus, options, rusage) — Wait for a child process to change state. The WNOHANG option makes it non-blocking. Inspect wstatus with WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG.

Memory management

mmap(addr, length, prot, flags, fd, offset) — Map files or devices into memory, or allocate anonymous memory with MAP_ANONYMOUS. The prot flags (PROT_READ | PROT_WRITE | PROT_EXEC) set page permissions enforced by the MMU. Returns the mapped address or MAP_FAILED (-1) on error.

mprotect(addr, len, prot) — Change permissions on an existing mapping. Used by runtimes to mark JIT-compiled pages executable after writing them.

Tracing with strace

# Trace all syscalls made by a program
strace ./myprogram

# Trace only specific syscalls
strace -e trace=openat,read,write ./myprogram

# Count syscalls and time spent in each (profile mode)
strace -c ./myprogram

# Attach to a running process
strace -p 1234

The output format is syscall_name(arg1, arg2, ...) = return_value. A return of -1 is followed by the errno name and description: openat(...) = -1 ENOENT (No such file or directory).

Tips and examples

  • Prefer the *at variants (openat, unlinkat, fstatat) for race-free path resolution relative to a directory file descriptor.
  • strace -c ./prog gives a histogram of which syscalls dominate — useful when a program feels slow or chatty.
  • The numbers here are x86-64 specific. The canonical table lives at arch/x86/entry/syscalls/syscall_64.tbl in the kernel source.
  • Use seccomp(SECCOMP_SET_MODE_FILTER, ...) with a BPF filter to restrict which syscalls a sandboxed process may make — this is how Docker and Chrome’s renderer use the syscall table as a security boundary.