Expand description
Output of a child captured into anonymous files, so that the child outlives the command that started it.
What:
Output of a child process captured into two anonymous files instead of two pipes, and read back from the start whenever the
caller asks.
Why:
A pipe lives only as long as the process that holds its read end. A step the wrapper leaves running (a write in place that
cannot be run twice and has outlasted its bound) would meet a closed pipe when it next wrote, if the command that started it
had exited: the write fails with EPIPE or the process dies of SIGPIPE, which is the cut the owner ruled out (“Never cut a
branch write (Recommended)”). A file the child holds open cannot be closed by the command, so the child outlives the command
and no thread has to read for it. The same holds for a repair tool that starts a helper which keeps its inherited output open
after the tool has exited: with files, no reader waits for the helper. The files are anonymous (no name to remove, nothing left
behind), the parent reads them by position so the offset the child moves is not disturbed, and a child that is still running
after the command has gone is reaped by the system’s init or subreaper.
In TS you’d write (pseudocode):
const capture = new Capture(); spawn(command, { stdio: ['null', capture.out, capture.err] }); await exit(child); const { stdout, stderr } = capture.read();Structs§
- Capture
- Two anonymous files that collect a child’s standard output and standard error.
- Captured
- What a snapshot of a child’s output holds.
Constants§
- STEP_
OUTPUT_ LIMIT - The most bytes of one stream a snapshot of a step’s output holds, the last ones. Exempt from a citation under
LQM(class: display cap): it limits how much of the output of a step the command keeps in memory for its messages, and no result depends on it; the steps that use it write a few lines (a reference update, a merge) or print a reason at the end (the repair tools).