Descriptor ownership and stream completion
What this concept is
A descriptor is a process-local handle with an owner responsible for its lifetime. A helper that borrows a descriptor must not silently close it. Copies and duplicates complicate when the underlying stream is actually finished.
Why it matters here
Pipe EOF depends on closing all write-end references, not on one helper returning. Cleanup decisions therefore affect observable protocol behavior as well as resource use.
Concrete example
The lab’s real-pipe smoke test creates both ends, passes the write end by borrowing, writes a tiny payload, then closes its write end before reading EOF. The helper never closes either end. A leaked duplicated write end could prevent EOF even though the expected bytes were read.
Common confusion / misconception
Closing an integer handle does not make every stored copy safe. Another open may reuse the number. Close-error handling is platform-sensitive; a blanket retry can target a reused descriptor on systems where the first close already released it. This smoke test is not a general transport loop.
How to use it
Draw a descriptor ownership map before fork/dup/exec exercises. Assign one owner to each acquired handle and list transfers and cleanup paths. Keep read/write progress errors distinct from cleanup diagnostics. In a generalized writer, explicitly address SIGPIPE, readiness and durability rather than assuming this tiny pipe test proves them.
Check yourself
Why can a pipe reader wait forever after receiving the entire expected payload? Who closes a borrowed descriptor? Why is closing a descriptor from another thread not a generic cancellation strategy?
Mini drill or application
Annotate the lab’s pipe lifecycle. Then draw a hypothetical duplicated write end and identify the extra close needed for EOF. Do not intentionally run an unbounded hanging test.
Read this only if stuck
The C Programming Language for pipes and descriptors; consult pipe(7) and close(2) for Linux-specific details and portability caveats.