Skip to content

Prep: cat — 11c

Session: Thursday Sep 24, 1h45 · Exercises: 11c_cat · Prep time: ~45 min · Lecture: Buffers, Bytes, and Line-Oriented I/O

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 the four calls from lecture §1: 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

Read before class

What Time
L07 §§1–4 25 min
L07 §7 (cat paragraph), §8 5 min
ulib guide § The complete API surface · § Portability rules 10 min
ulib guide § The host backend and the test harness 5 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

  1. read into a 512-byte buffer returns 300. Is the file finished?
    AnswerNo. Only 0 means 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 at 0.
  2. cat missing.txt real.txt — what goes to standard output, to standard error, and what exit status?
    Answerreal.txt's contents on standard output; a cannot open message naming missing.txt on standard error; exit status 1. Report, remember, continue: a failure is recorded, not returned from, so later files still print and the status stays non-zero.
  3. Tests are green, but you used bare write and never closed anything. What happens in December?
    AnswerThe 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 until open starts failing on good files.

What "done" looks like

oslings run is green, then oslings submit before you leave. Not green? Submit anyway (substantial credit), then finish by Thursday 11:59 pm and submit again.

If you finish early

Work lecture Problem 1 and Problem 2 (counting calls; four broken copy loops). 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; L07 §7 previews both.