A focused learning plan for Stewart N. Weiss’s book
A focused learning plan for Stewart N. Weiss’s book
A focused learning plan for Stewart N. Weiss’s book
16 WEEKS + 1 SETUP WEEK
Outcome
By the end, you will be able to write and debug C programs that interact directly with Linux files, processes, signals, interprocess communication (IPC), threads, terminals, and non-blocking input/output—and explain what the kernel is doing at each boundary.
The finish line
Read: All 19 chapters, in order.
Build: Every chapter’s practical work, plus four cumulative checkpoints.
Prove: A final ncurses system monitor that combines processes, signals, threads, and event-driven I/O.
The weekly operating system
Use the same four-session loop every week. The sequence matters: understand the model, touch the interface, build something, then consolidate the bugs.
Session
Time
Mode
Output
A
75 min
Read + annotate
Kernel boundary; API contract
B
75 min
Re-type examples
Compile; trace; vary inputs
C
3–4 hr
Chapter project
Working program + README
D
60–90 min
Debug + recall
Bug log + five questions
Your weekly time budget
Work
Typical
Heavy week
Reading
1.5 hr
2 hr
Code-along
1.5 hr
2 hr
Project
3 hr
4.5 hr
Review
1 hr
1.5 hr
Typical total: 7 hours. Heavy total: 10 hours. The full plan is approximately 131 hours; allow a 125–145 hour range because C debugging is variable.
Definition of done for every week
Builds cleanly: Use a Makefile and strict warnings; document any warning you intentionally suppress.
Runs under inspection: Use gdb, strace, or Valgrind where relevant—not only printf debugging.
Handles failure: Test at least one invalid argument, failed system call, interrupted call, or partial read/write.
Leaves a trace: Commit the code and a five-line README: purpose, build, run, design choice, known limit.
Setup week rebuilds only the C you need
Do not add a separate C course. Spend six hours on a compact readiness pass, then refresh deeper C concepts exactly when the book needs them.
1. Create the Linux lab — 60 minutes
Environment: Use native Linux or a Linux virtual machine. Avoid doing the core exercises directly on macOS; system calls and library behavior differ.
Toolchain: Install GCC or Clang, make, gdb, git, strace, and Valgrind. Create one repository with a directory per chapter.
Write a small command-line program that reads a text file, counts lines and bytes, stores the result in a struct, and reports errors through stderr. You are ready when it:
compiles with the strict flags above
uses argc and argv safely
checks every allocation and I/O result
has no invalid reads or leaks under Valgrind
can be stepped through in gdb
Phase 1 — Foundations become observable
Weeks 1–4 · Chapters 1–7 · 31 hours
Week
Read
Core focus
Build / proof
Hours
1
Ch. 1–2
Unix model; syscalls
errno probe + tracer
8
2
Ch. 3–4
time; descriptors
timestamped copier
8
3
Ch. 5
robust file I/O
who/cp-style utility
7
4
Ch. 6–7
inodes; directories
recursive inspector
8
How to use these four weeks
Read selectively: Read for the model and the interfaces. Stop copying prose into notes; capture only invariants, failure modes, and one example per system call.
Type the code: Re-enter important examples instead of pasting them. Compile after each meaningful change and predict the result before running.
Finish with evidence: Keep the source, Makefile, README, sample command, and a short note naming one bug you found and how you proved the fix.
Phase 2 — Processes become controllable
Weeks 5–8 · Chapters 8–11 · 30 hours
Week
Read
Core focus
Build / proof
Hours
5
Ch. 8
signals; handlers
signal-safe worker
7
6
Ch. 9
timers; sleeping
deadline utility
6
7
Ch. 10
process states
process observer
8
8
Ch. 11
fork; exec; wait
mini process runner
9
How to use these four weeks
Read selectively: Read for the model and the interfaces. Stop copying prose into notes; capture only invariants, failure modes, and one example per system call.
Type the code: Re-enter important examples instead of pasting them. Compile after each meaningful change and predict the result before running.
Finish with evidence: Keep the source, Makefile, README, sample command, and a short note naming one bug you found and how you proved the fix.
Phase 3 — Programs learn to cooperate
Weeks 9–12 · Chapters 12–15 · 30 hours
Week
Read
Core focus
Build / proof
Hours
9
Ch. 12
IPC choices
mechanism demos
6
10
Ch. 13
pipes; FIFOs
two-stage pipeline
8
11
Ch. 14
clients; daemons
local job service
8
12
Ch. 15
thread lifecycle
threaded workers
8
How to use these four weeks
Read selectively: Read for the model and the interfaces. Stop copying prose into notes; capture only invariants, failure modes, and one example per system call.
Type the code: Re-enter important examples instead of pasting them. Compile after each meaningful change and predict the result before running.
Finish with evidence: Keep the source, Makefile, README, sample command, and a short note naming one bug you found and how you proved the fix.
Phase 4 — Concurrency and I/O become robust
Weeks 13–16 · Chapters 16–19 · 34 hours
Week
Read
Core focus
Build / proof
Hours
13
Ch. 16
mutexes; conditions
bounded queue
10
14
Ch. 17
non-blocking I/O
event-driven server
8
15
Ch. 18
terminal modes
raw-input utility
7
16
Ch. 19
ncurses interface
system monitor
9
How to use these four weeks
Read selectively: Read for the model and the interfaces. Stop copying prose into notes; capture only invariants, failure modes, and one example per system call.
Type the code: Re-enter important examples instead of pasting them. Compile after each meaningful change and predict the result before running.
Finish with evidence: Keep the source, Makefile, README, sample command, and a short note naming one bug you found and how you proved the fix.
Four checkpoints prove understanding
A checkpoint is complete only when you can explain the behavior without reading the code. Use the same review rubric each time so progress is visible.
Gate
Question
Pass evidence
Correctness
Does it do the job?
happy + failure tests
Kernel model
Why this syscall?
call-path explanation
Resources
What must close/free?
clean exit; no leaks
Concurrency
What can interleave?
named invariant
Debugging
How was it proved?
trace or debugger note
Checkpoint review — 45 minutes
Demo cold: Clone or clean the build, compile, and run from the README without relying on shell history.
Explain one path: Narrate one request from user input to library call, system call, kernel state change, and return value.
Break it deliberately: Use a missing file, bad permission, early disconnect, signal, or forced timing race. Confirm the program fails predictably.
Record one correction: Write the initial misconception and the evidence that changed your mind.
Final self-test
Without notes, answer these in plain language. Any answer that takes more than two minutes becomes the first review item after the course.
What changes—and what does not—across fork()?
Why can read() or write() complete only part of the request?
What makes a function unsafe inside a signal handler?
When should a mutex be paired with a condition variable?
How does non-blocking I/O change program structure?
What terminal state must your program restore on exit?
Rules that keep C from eating the schedule
Use a debugging ladder
Minute
Action
Decision
0–10
read warning + errno
fix obvious contract
10–25
reduce the input
keep smallest failure
25–45
gdb or strace
locate boundary
45–60
Valgrind / sanitizer
check memory
60
write the hypothesis
stop random edits
Stop conditions
After 60 stuck minutes: Write the expected behavior, observed behavior, smallest reproducer, and next hypothesis. Then stop for the day.
After a two-week slip: Do not compress two projects into one weekend. Add a calendar week and keep the chapter order.
When examples work too easily: Change one assumption: short reads, invalid input, interruption, multiple clients, or early termination.
Notes that are worth keeping
System-call card: Purpose, inputs, return value, errno cases, resource ownership, and one portability warning.