ciosignalsbroken-pipesigpipe

How to prevent SIGPIPEs (or handle them properly)


I have a small server program that accepts connections on a TCP or local UNIX socket, reads a simple command and (depending on the command) sends a reply.

The problem is that the client may have no interest in the answer and sometimes exits early. So writing to that socket will cause a SIGPIPE and make my server crash.

What's the best practice to prevent the crash here? Is there a way to check if the other side of the line is still reading? (select() doesn't seem to work here as it always says the socket is writable). Or should I just catch the SIGPIPE with a handler and ignore it?


Solution

  • You generally want to ignore the SIGPIPE and handle the error directly in your code. This is because signal handlers in C have many restrictions on what they can do.

    The most portable way to do this is to set the SIGPIPE handler to SIG_IGN. This will prevent any socket or pipe write from causing a SIGPIPE signal.

    To ignore the SIGPIPE signal, use the following code:

    signal(SIGPIPE, SIG_IGN);
    

    If you're using the send() call, another option is to use the MSG_NOSIGNAL option, which will turn the SIGPIPE behavior off on a per call basis. Note that not all operating systems support the MSG_NOSIGNAL flag.

    Lastly, you may also want to consider the SO_NOSIGPIPE socket flag that can be set with setsockopt() on some operating systems (e.g. those derived from BSD). This will prevent SIGPIPE from being caused by writes just to the sockets it is set on.