linux-sysprog · advanced · ~35 min
The mental model of pipe-chain plumbing.
Work out the pipe plumbing for a shell pipeline like p0 | p1 | ... | p(N-1): for each process, which pipe it reads from and which it writes to. This is pure index arithmetic — no real pipes are created.
Implement void pipe_chain_plan(int n, int *read_for, int *write_for) that fills two length-n arrays describing each process's read and write end.
n: number of processes in the chain (n >= 1). Conceptually there are n - 1 pipes, numbered 0 .. n-2; pipe i connects process i (writer) to process i+1 (reader).read_for, write_for: output arrays, each with room for n ints.For each process i:
read_for[i] = the pipe number it reads from, or -1 if it reads from stdin (the first process).write_for[i] = the pipe number it writes to, or -1 if it writes to stdout (the last process).pipe_chain_plan(3, r, w)
-> r = [-1, 0, 1], w = [0, 1, -1]
pipe_chain_plan(1, r, w)
-> r = [-1], w = [-1] (lone process: stdin -> stdout)
n == 1: the single process reads stdin and writes stdout (both -1).a | b | c in shell becomes a chain of pipes between N processes. Computing which fd each child reads from / writes to is non-obvious — getting it right matters because tip-1 left-open fd leaks an unkillable EOF.
n (>= 1) processes; there are n-1 pipes numbered 0..n-2. Two output arrays read_for and write_for, each of length n.
read_for[i] = pipe it reads from or -1 (stdin); write_for[i] = pipe it writes to or -1 (stdout).
Process 0 reads stdin (-1); process n-1 writes stdout (-1); process i otherwise reads pipe i-1 and writes pipe i. No allocations.
void pipe_chain_plan(int n, int *read_for, int *write_for) { /* TODO */ }
Off-by-one (last process should write to stdout, not pipe N-1); reversing reader vs writer ends; using pipe i for both ends of two adjacent processes (instead of one end each).
N == 1: process reads stdin, writes stdout.
O(N).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.