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

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.