Pipes
A pipe is a unidirectional kernel buffer connecting two file descriptors — one write end and one read end. Created with pipe(int pipefd[2]). Both ends are regular file descriptors: they respect the three-table FD model, are inherited across fork(), and are closed with close().
The canonical pattern
int pipefd[2];
pipe(pipefd);
pid_t pid = fork();
if (pid == 0) {
close(pipefd[1]); // child doesn't write
// read from pipefd[0]...
_exit(0);
}
close(pipefd[0]); // parent doesn't read
// write to pipefd[1]...The most common pipe bug: forgetting to close the unused end. If the parent keeps pipefd[0] open, the child’s read() will never return EOF — the kernel sees a writer still alive.
Key properties
- Kernel-buffered (typically 64 KiB on Linux)
read()blocks until data is available or all write ends are closedwrite()to a pipe with no readers deliversSIGPIPE; usesignal(SIGPIPE, SIG_IGN)orMSG_NOSIGNAL/O_NONBLOCKfor servers
In the curriculum
Covered in m07-processes-signals lesson 7-3 (“Pipes and IPC”). The Minimal Shell project (7-proj) uses pipes for command pipelines. Also relevant to m08-sockets-networking — sockets are generalised pipes over a network.