Prep: cat — 11c¶
Session: Thu Sep 24, 1h45 · Exercises: 11c_cat · Prep time: ~25 min · Lecture: Week 5 · Streams of Bytes
What you will build¶
A cat that streams. Named files are copied to standard output in order with nothing between them; with no arguments it copies standard input, so it works inside a pipeline. Every byte moves through one fixed buffer via four calls: open, read, write (always through write_all), and close. A file that cannot be opened gets a message on standard error, the remaining files still print, and the exit status ends up non-zero. The tests feed in-memory files — one larger than the buffer, one missing — and check the bytes on standard output, the cannot open message on standard error, and the exit code.
Concepts you need¶
- File descriptors and the three standard streams — Week 5 · Everything is a descriptor · ulib guide: The complete API surface
- The short-read contract;
0is the only end of file — Week 5 · The short-read contract, Counting the calls · ulib guide: The complete API surface - Short writes,
write_all, and what the harness cannot check — Week 5 · The short-read contract, Whywrite_allexists · ulib guide: The host backend and the test harness - One fixed buffer, no allocator — Week 5 · One fixed buffer · ulib guide: Portability rules a command must follow
openwithO_RDONLY,close, and descriptor leaks — Week 5 · Everything is a descriptor · ulib guide: The complete API surfaceResult,?, and the exit status — Week 5 · One bad file, one exit status, Week 4 ·?, and where aResultbecomes a number · ulib guide:ulib::main!, what it expands to
Read before class¶
| What | Time |
|---|---|
Week 5 · This week, then Thursday · 11c cat, all four sections |
8 min |
Week 5 · For the exam: Counting the calls and Why write_all exists. Not needed today; on Midterm 1 |
2 min |
| ulib guide: The complete API surface and Portability rules a command must follow | 6 min |
| ulib guide: The host backend and the test harness | 2 min |
Mental model¶
A 300-byte file copied through a 128-byte buffer into a pipe with room for only 100 bytes when the first write lands:
read -> 128 write_all(&buf[..128]): write -> 100, write -> 28
read -> 128 write_all(&buf[..128]): write -> 128
read -> 44 write_all(&buf[..44]): write -> 44
read -> 0 stop: 300 bytes out
Three details matter. The loop ends on 0 and nothing else; the 44 is a normal short read. The slice handed to the writer is ..n, because bytes past n are leftovers from the previous round. And write_all absorbed a short write that bare write would have dropped silently. Your Module 2 kernel sits on the far side of these same calls with a 128-byte staging buffer and no allocator; this loop is what its trap path looks like from the inside.
Check yourself¶
readinto a 512-byte buffer returns 300. Is the file finished?Answer
No. Only0means end of file; the 300 might be the file's last bytes, a pipe's contents so far, or a kernel clipping the request. Read again; stop at0.cat missing.txt real.txt— what goes to standard output, to standard error, and what exit status?Answer
real.txt's contents on standard output; acannot openmessage namingmissing.txton standard error; exit status 1. A failure is recorded, not returned from, so later files still print and the status stays non-zero.- Tests are green, but you used bare
writeand never closed anything. What happens in December?Answer
The host harness accepts every write whole and grows its descriptor table, so it sees neither bug. On rv6 a short write silently truncates output, and each unclosed descriptor holds a slot in a small fixed table untilopenstarts failing on good files.
What "done" looks like¶
oslings run is green, then oslings submit before you leave. Not green? Submit anyway — the tests that pass earn their share — then finish it at a make-up session (office hours, on the class network) for three quarters, or anywhere else for half, and submit again.
If you finish early¶
Work Week 5 · Problem 1: Counting the calls on paper (Midterm 1 material). Then Rustlings error_handling, options, primitive_types; 100 Exercises To Learn Rust chapter 5 (Result and ?) and chapter 6 (arrays and slices). Friday's 12c_wc and 13c_grep build on this loop: read Week 5 · Friday · 12c wc, or start Friday's prep page, Prep: wc and grep.