Appendix C: Linux System Call Reference
This appendix provides a categorized reference of the key system calls covered in this book. For each syscall: the signature, purpose, common errno values, and the chapter where it's covered in detail.
File I/O
open
#include <fcntl.h>
int open(const char *pathname, int flags, ... /* mode_t mode */);
Opens or creates a file. Returns a file descriptor.
Flags: O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC, O_APPEND,
O_NONBLOCK, O_CLOEXEC.
Errno: ENOENT (not found), EACCES (permission), EEXIST (with
O_EXCL), EMFILE (too many open fds).
Chapter: 28 (File Descriptors)
read / write
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
Read/write bytes. May transfer fewer than requested (short read/write).
Errno: EBADF (bad fd), EINTR (interrupted by signal), EAGAIN
(non-blocking and would block), EIO (hardware error).
Chapter: 28-29 (File I/O)
close
#include <unistd.h>
int close(int fd);
Closes a file descriptor. Releases kernel resources.
Errno: EBADF (not a valid fd), EIO (error flushing data).
Chapter: 28
lseek
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
Repositions file offset. whence: SEEK_SET, SEEK_CUR, SEEK_END.
Errno: EBADF, EINVAL (invalid whence), ESPIPE (fd is a pipe).
Chapter: 29
stat / fstat / lstat
#include <sys/stat.h>
int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf); /* doesn't follow symlinks */
Get file metadata: size, permissions, timestamps, inode.
Errno: ENOENT, EACCES, EBADF (fstat).
Chapter: 30
dup2
#include <unistd.h>
int dup2(int oldfd, int newfd);
Duplicates oldfd to newfd, closing newfd first if open.
Errno: EBADF, EMFILE.
Chapter: 31
sendfile
#include <sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
Zero-copy transfer between file descriptors (in_fd must be mmappable).
Errno: EAGAIN, EBADF, EINVAL (fd types not supported).
Chapter: 52
mmap / munmap
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *addr, size_t length);
Map files or devices into memory. Also used for anonymous memory allocation.
Prot: PROT_READ, PROT_WRITE, PROT_EXEC.
Flags: MAP_SHARED, MAP_PRIVATE, MAP_ANONYMOUS, MAP_FIXED.
Errno: EACCES, ENOMEM, EINVAL (bad alignment or length).
Chapter: 39
Process Management
fork
#include <unistd.h>
pid_t fork(void);
Creates a child process. Returns 0 in child, child PID in parent, -1 on error.
Errno: ENOMEM, EAGAIN (process limit).
Chapter: 32
exec family
#include <unistd.h>
int execve(const char *path, char *const argv[], char *const envp[]);
int execvp(const char *file, char *const argv[]);
int execlp(const char *file, const char *arg, ... /* (char *)NULL */);
Replace current process image. Does not return on success.
Errno: ENOENT, EACCES, ENOEXEC (bad format).
Chapter: 33
wait / waitpid
#include <sys/wait.h>
pid_t wait(int *wstatus);
pid_t waitpid(pid_t pid, int *wstatus, int options);
Wait for child process state change. Use WIFEXITED, WEXITSTATUS macros
to interpret status.
Options: WNOHANG (don't block), WUNTRACED.
Errno: ECHILD (no children), EINTR.
Chapter: 33
_exit / exit_group
#include <unistd.h>
void _exit(int status);
Terminate process immediately (no atexit handlers, no stdio flush).
Chapter: 32
getpid / getppid
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
Get current process ID or parent process ID. Never fails.
Chapter: 32
Signal Handling
sigaction
#include <signal.h>
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
Set signal handler with full control over flags and signal mask.
Errno: EINVAL (invalid signal or attempt to handle SIGKILL/SIGSTOP).
Chapter: 35-36
kill
#include <signal.h>
int kill(pid_t pid, int sig);
Send signal to process or process group.
Errno: ESRCH (no such process), EPERM (permission).
Chapter: 35
sigprocmask
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
Block or unblock signals. how: SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK.
Chapter: 36
signalfd
#include <sys/signalfd.h>
int signalfd(int fd, const sigset_t *mask, int flags);
Receive signals via a file descriptor (pollable).
Errno: EINVAL, ENOMEM.
Chapter: 37
Memory Management
brk / sbrk
#include <unistd.h>
int brk(void *addr);
void *sbrk(intptr_t increment);
Adjust the program break (heap end). Rarely used directly; malloc calls
these internally.
Chapter: 38
mprotect
#include <sys/mman.h>
int mprotect(void *addr, size_t len, int prot);
Change protection on a memory region.
Errno: EACCES, EINVAL, ENOMEM.
Chapter: 39
madvise
#include <sys/mman.h>
int madvise(void *addr, size_t length, int advice);
Advise kernel on memory usage patterns. MADV_SEQUENTIAL, MADV_DONTNEED,
MADV_HUGEPAGE.
Chapter: 39
IPC (Inter-Process Communication)
pipe / pipe2
#include <unistd.h>
int pipe(int pipefd[2]);
int pipe2(int pipefd[2], int flags); /* O_CLOEXEC, O_NONBLOCK */
Create a unidirectional data channel. pipefd[0] for reading, pipefd[1]
for writing.
Errno: EMFILE, ENFILE.
Chapter: 34
socketpair
#include <sys/socket.h>
int socketpair(int domain, int type, int protocol, int sv[2]);
Create a pair of connected sockets (bidirectional pipe).
Chapter: 34
shmget / shmat / shmdt
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
System V shared memory. Prefer mmap(MAP_SHARED) for new code.
Chapter: 40
Networking
socket
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
Create a socket. Returns a file descriptor.
Domain: AF_INET, AF_INET6, AF_UNIX, AF_NETLINK.
Type: SOCK_STREAM (TCP), SOCK_DGRAM (UDP), SOCK_RAW.
Errno: EAFNOSUPPORT, EMFILE, ENOMEM.
Chapter: 47
bind
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
Assign address to socket.
Errno: EADDRINUSE, EACCES (privileged port), EINVAL.
Chapter: 47
listen / accept
int listen(int sockfd, int backlog);
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
Listen for connections and accept them.
Errno: EAGAIN (non-blocking), EMFILE, EINTR.
Chapter: 47-48
connect
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
Connect to a remote address.
Errno: ECONNREFUSED, ETIMEDOUT, ENETUNREACH, EINPROGRESS
(non-blocking).
Chapter: 47
send / recv / sendto / recvfrom
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest, socklen_t addrlen);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src, socklen_t *addrlen);
Send/receive data on sockets. sendto/recvfrom for UDP.
Flags: MSG_DONTWAIT, MSG_PEEK, MSG_NOSIGNAL.
Chapter: 47-48
epoll_create1 / epoll_ctl / epoll_wait
#include <sys/epoll.h>
int epoll_create1(int flags);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
Scalable I/O event notification. op: EPOLL_CTL_ADD, EPOLL_CTL_MOD,
EPOLL_CTL_DEL.
Chapter: 49
Device Interaction
ioctl
#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);
Device-specific control operations.
Errno: ENOTTY (wrong device type), EINVAL (bad request), EFAULT
(bad pointer).
Chapter: 54
Thread-Related
clone (underlying syscall for pthread_create)
#include <sched.h>
int clone(int (*fn)(void *), void *stack, int flags, void *arg, ...);
Create a new process/thread with fine-grained sharing control.
Flags: CLONE_VM, CLONE_FILES, CLONE_SIGHAND, CLONE_THREAD.
Chapter: 41
futex
#include <linux/futex.h>
long futex(uint32_t *uaddr, int futex_op, uint32_t val, ...);
Fast user-space locking primitive. Used by pthread mutex implementation.
Operations: FUTEX_WAIT, FUTEX_WAKE.
Chapter: 44
Miscellaneous
getrandom
#include <sys/random.h>
ssize_t getrandom(void *buf, size_t buflen, unsigned int flags);
Cryptographically secure random bytes.
Flags: GRND_NONBLOCK, GRND_RANDOM.
Chapter: Referenced in security discussions
prctl
#include <sys/prctl.h>
int prctl(int option, unsigned long arg2, ...);
Process-specific operations: set name, enable seccomp, control dumpability.
seccomp
#include <linux/seccomp.h>
int seccomp(unsigned int operation, unsigned int flags, void *args);
Restrict available system calls for sandboxing.
Syscall Invocation
All the above are libc wrappers. The actual syscall instruction:
#include <sys/syscall.h>
#include <unistd.h>
/* Direct syscall (bypassing libc) */
long result = syscall(SYS_write, STDOUT_FILENO, "hello\n", 6);
On x86-64, this becomes:
mov rax, 1 ; syscall number for write
mov rdi, 1 ; fd = stdout
lea rsi, [msg] ; buffer
mov rdx, 6 ; count
syscall
Registers: rax = syscall number, rdi = arg1, rsi = arg2, rdx = arg3,
r10 = arg4, r8 = arg5, r9 = arg6. Return value in rax.