Rust ports of the example programs from The Linux Programming Interface (Kerrisk, 2010), updated to cover Linux APIs through kernel 6.x.
All 391 C example programs are being recreated as idiomatic Rust — not mechanical transliterations of C, but programs that leverage Rust's type system, iterator model, and ownership semantics while demonstrating the same Linux kernel interfaces.
Current status: 369 binaries implemented across 54 workspace members.
The primary syscall layer is rustix — a safe,
zero-overhead Rust crate that wraps Linux syscalls with typed return values and OwnedFd
rather than raw i32. Where rustix has gaps, nix fills
them. libc is used only as a last resort for APIs that neither crate provides.
rustix → ~70% of TLPI topics (fs, process, net, mm, event, time, io_uring, mount)
nix → ~25% (POSIX mqueues, fanotify, epoll, user DB, dup2, clock_nanosleep)
libc → ~5% (SysV IPC, POSIX named semaphores, mq_notify, sched_setscheduler, sigwaitinfo)
The crate selection rationale and every libc:: call is audited in
dev_docs/c_interop.md.
Each TLPI chapter maps to one Cargo workspace member. tlpi_common is a shared utility
library (error types, daemon helpers, ename tables).
| Member | TLPI Chapter(s) | Binaries | Primary crates |
|---|---|---|---|
tlpi_common |
shared library | — | rustix, nix, thiserror |
getopt |
§20 getopt | 1 | rustix |
fileio |
§4–5 File I/O | 9 | rustix, nix |
filebuff |
§13 Buffering | 5 | rustix, nix |
filelock |
§55 File locking | 4 | rustix, nix |
files |
§15 File metadata | 7 | rustix |
dirs_links |
§18 Directories & links | 8 | rustix, nix |
xattr |
§16 Extended attributes | 2 | rustix |
mmap |
§49 Memory-mapped files | 6 | rustix |
memalloc |
§7 Memory allocation | 1 | rustix |
vmem |
§50 Virtual memory | 4 | rustix |
proc |
§6 Process environment | 9 | rustix |
proccred |
§9 Process credentials | 1 | rustix |
users_groups |
§8 Users & groups | 4 | nix |
procexec |
§24–28 fork/exec/wait | 33 | rustix, nix |
sysinfo |
§11–12 System info | 3 | rustix |
signals |
§20–22 Signals | 19 | nix, rustix |
time |
§10 Time & clocks | 6 | rustix, libc |
timers |
§23 POSIX timers | 11 | rustix, nix, libc |
pgsjc |
§34 Process groups & sessions | 6 | rustix, nix |
altio |
§63 Multiplexed I/O | 8 | nix, rustix |
acl |
§17 POSIX ACLs | 2 | posix-acl |
io_uring |
§63 io_uring | 5 | io-uring, libc |
sockets |
§56–61 Sockets | 31 | rustix, nix |
pipes |
§44 Pipes & FIFOs | 7 | rustix, nix |
pidfd |
§22 pidfds | 5 | rustix, nix, libc |
procpri |
§35 Scheduling & priority | 6 | nix, libc |
procres |
§36 Resource limits | 5 | rustix |
progconc |
§30 POSIX semaphores (unnamed) | 1 | libc |
daemons |
§37 Daemons | 4 | rustix, libc |
threads |
§29–33 POSIX threads | 20 | std::thread, std::sync, libc |
inotify |
§19 inotify / fanotify | 8 | nix, rustix |
svipc |
§45 SysV IPC overview | 2 | libc |
svmsg |
§46 SysV message queues | 9 | libc |
svsem |
§47 SysV semaphores | 11 | libc |
svshm |
§48 SysV shared memory | 9 | libc |
pmsg |
§52 POSIX message queues | 11 | nix, libc |
psem |
§53 POSIX semaphores (named) | 8 | libc |
pshm |
§54 POSIX shared memory | 4 | rustix |
loginacct |
§40 Login accounting | 3 | libc |
tty |
§62 Terminals | 6 | nix, libc |
pty |
§64 Pseudoterminals | 5 | rustix, libc |
shlibs |
§41–42 Shared libraries | 4 | libloading, elf, metagoblin |
cap |
§39 Capabilities | 9 | caps |
seccomp |
§63 Seccomp / Landlock | 13 | libseccomp, landlock |
namespaces |
§28 Linux namespaces | 17 | rustix, nix |
cgroups |
§49 cgroups v2 | 7 | cgroups-rs, rustix |
filesys |
§14 Filesystems | 7 | rustix, libc |
vdso |
§3 vDSO | 1 | libc |
syslim |
§11 System limits | 2 | nix |
| Total | 369 |
| Crate | Version | Role |
|---|---|---|
rustix |
1.x | Primary syscall layer — safe typed wrappers via inline asm; covers fs, process, net, mm, time, event, io_uring, mount |
nix |
0.29 | POSIX bindings for what rustix lacks: fanotify, epoll, POSIX mqueues, user DB, clock_nanosleep, sched_setaffinity |
libc |
0.2 | Escape hatch for SysV IPC, POSIX named semaphores, mq_notify, sched_setscheduler, sigwaitinfo |
caps |
0.5 | Linux capability manipulation (wraps libcap) |
libseccomp |
0.3 | BPF seccomp filter construction — ALLOW, ERRNO, TRAP, LOG, KILL actions |
landlock |
0.4 | Landlock LSM (Linux 5.13+) — filesystem and network sandboxing |
io-uring |
0.7 | io_uring submission/completion queue without an async runtime |
posix-acl |
1.x | POSIX ACL get/set (wraps libacl) |
libloading |
0.9 | Safe dlopen/dlsym/dlclose with lifetime-tracked Symbol<T> |
elf |
0.8 | Zero-copy ELF parser — sections, symbols, .dynamic |
metagoblin |
0.10 | GNU symbol version table parser (.gnu.version_r, VERDEF) |
cgroups-rs |
0.5 | cgroup v1 and v2 management via /sys/fs/cgroup |
anyhow |
1.x | Type-erased error propagation in main() |
thiserror |
2.x | Typed error enums in library crates |
# Prerequisites
cargo install cargo-nextest cargo-llvm-cov cargo-deny cargo-machete just
# Compile the workspace
cargo check --workspace
# Build all binaries
cargo build --workspace
# Run a specific binary
cargo run -p fileio --bin copy -- src.txt dst.txt
cargo run -p signals --bin ouch# Full quality gate (fmt → clippy → check → test → coverage)
just
# Individual steps
cargo fmt --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo nextest run --workspace
# Single crate
cargo nextest run -p signals
# Coverage report (HTML)
just cov-html
# Run destructive [A]-tagged tests (requires root / privileged container)
TLPI_ALLOW_DESTRUCTIVE=1 cargo nextest run --workspace --run-ignored=all# Build the test image
just container-build
# Non-destructive tests (CI default)
just container-test
# Full privileged test suite (all [A]-tagged tests)
just container-test-privilegedThe Docker image is a multi-stage Ubuntu 24.04 build with Rust stable + nightly,
cargo-nextest, cargo-llvm-cov, just, and all required native libraries
(libseccomp-dev, libacl1-dev, etc.) pre-installed.
Tests are classified by the resources they require:
| Tag | Meaning | How to run |
|---|---|---|
| (none) | Pure unit or integration test; no special privileges | cargo nextest run |
[A] |
Requires container / namespace isolation (CAP_SYS_ADMIN, etc.) |
TLPI_ALLOW_DESTRUCTIVE=1 + privileged container |
[B] |
Creates files — uses tempfile crate, never hardcoded /tmp paths |
Always safe |
[C] |
Signal/process operations; requires an explicit target PID as CLI arg | Manual only |
[D] |
POSIX IPC objects — names prefixed /tlpi-test-{pid}- to avoid collisions |
TLPI_ALLOW_DESTRUCTIVE=1 |
Destructive tests are #[ignore] by default and check TLPI_ALLOW_DESTRUCTIVE=1 at
runtime before proceeding.
- Idiomatic Rust, not transliterated C — iterators over index loops,
?propagation,match/if letover boolean checks, newtypes for raw integers crossing API boundaries. - No
unwrap()outside tests — every fallible call propagates via?. unsaferequires a justification comment on the immediately preceding line.- Every
src/bin/*.rshas a//!doc comment explaining the TLPI section, the Linux concept, the key syscall(s), and any non-obvious kernel behaviour. libcusage is audited —dev_docs/c_interop.mddocuments everylibc::call and whether a rustix/nix replacement exists or why libc must be kept.
| File | Contents |
|---|---|
dev_docs/plan.md |
Full implementation checklist — one [x]/[ ] item per binary; chapter-by-chapter status |
dev_docs/rust-guidance.md |
Rust idioms, error handling patterns, crate priority rules, nix 0.29 API coverage, safety/unsafe rules, clippy/fmt config |
dev_docs/dev_guidance.md |
Workflow commands, quality gate, agent workflow (git worktrees, TDD loop), testing conventions, commit discipline |
dev_docs/build_and_test_guidance.md |
Deep-dive into Cargo.toml, justfile, Dockerfile, deny.toml, rustfmt.toml, nextest profiles, coverage exclusion list, devcontainer |
dev_docs/c_interop.md |
Full audit of every libc:: call — ✓ Replace / ✗ Keep / ~ Partial; §§1–45 |
dev_docs/safe-container-testing-plan.md |
Design rationale for the Docker-based privileged test infrastructure |
- The Linux Programming Interface — Michael Kerrisk, No Starch Press, 2010
- TLPI C source listings
- rustix documentation
- nix documentation
- Linux man pages