Who invented SIGPIPE, and why did they think it was a good idea?

Sep 13, 2012 23:55

I've been working with Posix/Unix-like systems for years, and this keeps catching me out. Again and again. Every two or three years or so. And it's stupid.

SIGPIPE - Broken pipe: write to pipe with no readers

If you write data to a pipe, a one-way communications channel from one program to another on the same computer, and the "reader" side of the pipe has died, this is an error. That's kind of expected. Fortunately, we have a way of communicating errors to "write"rs, and that is that the call to "write" returns an error code (-1) indicating that it's failed. Great. This is the mechanism we use to tell if a "write" to other file-like objects has failed, like to an actual file (e.g. because the disk is full) or to a network socket (e.g. because someone's pulled the network cable out.) Alternatively, there are a number of other functions you can call (select, poll, epoll) to specifically ask if there are errors with file-like objects (files/pipes/sockets).

But, no. That would be too easy.

If the failed write is to a pipe, but not to any other kind of file-like object, your program gets sent a SIGPIPE signal. That would not be too bad in itself, except for the fact that if your program gets sent a SIGPIPE, the default action is to terminate your program!

What. The. Frack?

According to The TTY demystified "This is useful, because otherwise jobs like yes | head would never terminate." Unless, you know, the "yes" program was smart enough to check the return code of its "write" calls!

Seriously, why did anyone think SIGPIPE was a good idea? What problem does it actually solve that can't be solved more easily and cleanly some other way?

Instead, every few years or so, a program of mine starts dying unexpectedly. There's no error message. There's no core dump. Debuggers, virtualised environments (e.g. valgrind), and the liberal sprinkling of printfs don't show anything obvious. The bug doesn't necessarily happen in a predictable place - signals are asynchronous. After a few days of banging my head on the desk, I finally figure it out, and sprinkle signal(SIGPIPE, SIG_IGN); to the start of my programs so they ignore the stupid broken pipe signals.

Bah!

posix, linux, suck

Previous post Next post
Up