Operating Systems Cheatsheet
System Calls
Use this Operating Systems reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
What is a System Call?
A system call is the mechanism by which a user-space process requests a service from the OS kernel. It is the only sanctioned way to transition from user mode (ring 3) to kernel mode (ring 0).
Execution path:
User program → calls library wrapper (e.g., libc write()) → wrapper puts syscall number in register (Linux: RAX) → executes SYSCALL instruction (x86-64) / SVC (AArch64) → CPU raises privilege; jumps to kernel entry point → kernel dispatches via syscall table → kernel executes service, places result in RAX → SYSRET; CPU lowers privilege → library returns to program
Key point: the application never directly executes kernel code — it traps into it.
x86-64 Linux Syscall Convention
| Register | Role |
|---|---|
rax | Syscall number (in), return value (out) |
rdi | Argument 1 |
rsi | Argument 2 |
rdx | Argument 3 |
r10 | Argument 4 |
r8 | Argument 5 |
r9 | Argument 6 |
Negative return value = errno negated (e.g., -2 = ENOENT).
; write(1, "hi\n", 3) mov rax, 1 ; sys_write mov rdi, 1 ; fd = stdout lea rsi, [msg] ; buf mov rdx, 3 ; count syscall
System Call Categories
Process Control
| Syscall | Signature | Description |
|---|---|---|
fork | pid_t fork(void) | Clone process |
execve | int execve(path, argv[], envp[]) | Replace process image |
exit | void exit(int status) | Terminate process |
wait / waitpid | pid_t wait(int *status) | Wait for child |
getpid / getppid | pid_t getpid(void) | Get process ID |
kill | int kill(pid_t pid, int sig) | Send signal |
signal / sigaction | int sigaction(signum, act, old) | Install signal handler |
nice | int nice(int inc) | Adjust scheduling priority |
clone | long clone(flags, …) | Create thread (Linux-specific) |
File Management
| Syscall | Signature | Description |
|---|---|---|
open | int open(path, flags, mode) | Open/create file |
close | int close(int fd) | Close file descriptor |
read | ssize_t read(fd, buf, count) | Read bytes |
write | ssize_t write(fd, buf, count) | Write bytes |
lseek | off_t lseek(fd, offset, whence) | Reposition |
stat / fstat | int fstat(fd, struct stat*) | Get file metadata |
unlink | int unlink(path) | Delete file |
rename | int rename(old, new) | Rename/move |
chmod | int chmod(path, mode) | Change permissions |
dup / dup2 | int dup2(oldfd, newfd) | Duplicate fd |
Directory & Filesystem
| Syscall | Description |
|---|---|
mkdir(path, mode) | Create directory |
rmdir(path) | Remove empty directory |
chdir(path) | Change working directory |
getcwd(buf, size) | Get working directory |
opendir / readdir | Iterate directory entries (libc wrappers) |
mount(src, tgt, fs, flags, data) | Mount filesystem |
umount(path) | Unmount |
link(old, new) | Create hard link |
symlink(target, path) | Create symbolic link |
readlink(path, buf, n) | Read symlink target |
Memory Management
| Syscall | Signature | Description |
|---|---|---|
brk / sbrk | int brk(void *addr) | Extend/shrink heap (old) |
mmap | void *mmap(addr, len, prot, flags, fd, off) | Map file/anonymous memory |
munmap | int munmap(void *addr, size_t len) | Unmap |
mprotect | int mprotect(addr, len, prot) | Change page permissions |
madvise | int madvise(addr, len, advice) | Hint to OS (MADV_DONTNEED, …) |
msync | int msync(addr, len, flags) | Sync mmap'd region to disk |
Inter-Process Communication
| Syscall | Description |
|---|---|
pipe(fd[2]) | Create anonymous pipe |
socket(domain, type, proto) | Create socket |
bind, listen, accept, connect | TCP/UDP setup |
send / recv | Socket I/O |
shmget, shmat, shmdt | System V shared memory |
semget, semop, semctl | System V semaphores |
msgget, msgsnd, msgrcv | System V message queues |
mq_open, mq_send, mq_receive | POSIX message queues |
eventfd(initval, flags) | File descriptor for event notification |
signalfd, timerfd_create | Signal/timer as fd (Linux) |
Device & I/O Control
| Syscall | Description |
|---|---|
ioctl(fd, request, arg) | Device-specific control |
select(n, readfds, …, timeout) | Wait for fd readiness |
poll(fds, nfds, timeout) | Wait for fd events |
epoll_create, epoll_ctl, epoll_wait | Scalable event polling |
read / write on /dev/* | Character/block device I/O |
fsync(fd) | Flush data + metadata to disk |
fdatasync(fd) | Flush data only (faster) |
Errno: Common Error Codes
| Code | Value | Meaning |
|---|---|---|
EPERM | 1 | Operation not permitted |
ENOENT | 2 | No such file or directory |
EINTR | 4 | Interrupted by signal |
EIO | 5 | I/O error |
EBADF | 9 | Bad file descriptor |
EAGAIN / EWOULDBLOCK | 11 | Resource temporarily unavailable (aliases on Linux) |
ENOMEM | 12 | Out of memory |
EACCES | 13 | Permission denied |
EFAULT | 14 | Bad address (pointer into invalid memory) |
EBUSY | 16 | Device or resource busy |
EEXIST | 17 | File exists |
EINVAL | 22 | Invalid argument |
EMFILE | 24 | Too many open files (per process) |
ENOSPC | 28 | No space left on device |
EPIPE | 32 | Broken pipe |
ENOTSUP | 95 | Operation not supported |
ETIMEDOUT | 110 | Connection timed out |
ssize_t n = read(fd, buf, 512); if (n < 0) { perror("read"); // prints: "read: No such file or directory" fprintf(stderr, "errno=%d\n", errno); // errno is thread-local }
Signal Numbers (Linux x86-64)
| Signal | Number | Default action | Common cause |
|---|---|---|---|
SIGHUP | 1 | Terminate | Terminal hangup |
SIGINT | 2 | Terminate | Ctrl+C |
SIGQUIT | 3 | Core dump | Ctrl+\\ |
SIGILL | 4 | Core dump | Illegal instruction |
SIGTRAP | 5 | Core dump | Breakpoint (debugger) |
SIGABRT | 6 | Core dump | abort() |
SIGFPE | 8 | Core dump | Floating point exception |
SIGKILL | 9 | Terminate | Cannot be caught/ignored |
SIGSEGV | 11 | Core dump | Segmentation fault |
SIGPIPE | 13 | Terminate | Write to closed pipe |
SIGALRM | 14 | Terminate | alarm() timer expired |
SIGTERM | 15 | Terminate | Graceful termination request |
SIGCHLD | 17 | Ignore | Child stopped/terminated |
SIGCONT | 18 | Continue | Resume stopped process |
SIGSTOP | 19 | Stop | Cannot be caught/ignored |
SIGTSTP | 20 | Stop | Ctrl+Z |
SIGUSR1/2 | 10/12 | Terminate | User-defined |
POSIX fixes signal names and default actions, not numbers. On macOS/BSD the numbers differ:
SIGSTOP=17,SIGTSTP=18,SIGCONT=19,SIGCHLD=20,SIGUSR1/2=30/31. Writekill -TERM, notkill -15, in portable scripts.
Linux-Specific High-Performance Syscalls
| Syscall | Purpose |
|---|---|
io_uring_setup, io_uring_enter, io_uring_register | Async I/O via shared ring buffers: setup creates rings, enter submits/reaps, register pins buffers/fds; batch many ops per syscall |
sendfile(out, in, off, count) | Zero-copy file-to-socket transfer |
splice(fd_in, …, fd_out, …) | Move data between fds without user-space copy |
tee(fd_in, fd_out, len, flags) | Duplicate pipe data without consuming |
vmsplice | Transfer user memory into pipe |
getrandom(buf, len, flags) | Cryptographic random bytes |
seccomp(op, flags, prog) | Restrict syscall set (sandboxing) |
ptrace(request, pid, addr, data) | Process tracing (debuggers, strace) |