Inter-Process Communication

the SIGPIPE/broken-pipe hazard

Picture pouring water into a hose while, unnoticed by you, someone yanks the far end out of the drain and walks off. Where does the water go? There is nowhere for it to land. When a process writes to a pipe, FIFO, or socket whose reading end has all been closed — the reader exited, crashed, or hung up — the same thing happens: there is no one to receive the bytes. The system has to do something definite about this, and what it does can surprise you badly.

By default, the kernel's response is to send the writer the SIGPIPE signal, and SIGPIPE's default action is to terminate the process. So a program that keeps writing to a vanished reader does not get a polite error code — it is silently killed. This is exactly why piping a long-running command into head can make the producer disappear: head reads a few lines and exits, closing the read end; the producer's next write triggers SIGPIPE and it dies. It is intentional and usually convenient (it stops a producer that has no audience), but if you did not expect it, it looks like a baffling crash with no message.

The fix is to take control of the disposition. You ignore SIGPIPE — signal(SIGPIPE, SIG_IG) or via sigaction — and then write() no longer kills you; instead it returns -1 with errno set to EPIPE, a normal error you can check and handle (close the connection, log it, move on). Network servers do this universally, because a client disconnecting mid-response must not crash the server. The precise mental model: a 'broken pipe' is the reader being gone; SIGPIPE is the asynchronous notification of it; EPIPE is the synchronous error you get instead once you have asked to ignore the signal. Handle one of the two, always, on any channel whose reader might leave first.

$ yes | head -n 3 # head exits after 3 lines; yes gets SIGPIPE and quietly stops In code, to handle it instead of dying: signal(SIGPIPE, SIG_IGN); ssize_t n = write(fd, buf, len); if (n < 0 && errno == EPIPE) { /* reader gone */ }

Default: writing to a dead reader kills you via SIGPIPE. Ignore the signal and you get EPIPE to handle instead.

Unhandled, SIGPIPE silently terminates the writer with no error message — a classic 'my server vanished when the client disconnected' bug. Ignore SIGPIPE (or use MSG_NOSIGNAL on sockets) so a broken pipe becomes a checkable EPIPE instead.

Also called
broken pipeEPIPEwriting to a closed reader管線中斷broken pipe 錯誤