Skip to content
Advertisement

SIGPIPE in C++ determining which TCP socket is disconnected

I’m using Linux/Ubuntu. I’ve written a pair of classes that implement a TCP server and TCP client, respectively. Part of the code is to have graceful recovery from disconnects. My only problem is with SIGPIPE. I’ve written code to capture the signal, but I’d like it to start the “attempt to reconnect” process on the class instance that hit the broken pipe. signal( SIGPIPE, functionname ) requires function name to be C-type function or static class method.

How can I determine which socket the SIGPIPE occurred for if I’ve got multiple instances of my classes in an application?

Advertisement

Answer

SIGPIPE is useless for TCP. This signal was invented for shell pipes (e.g. proc_1 | proc_2 | proc_3), because SIGINT is only delivered to the last process in the shell pipe. When the last process is killed and the previous process tries to write into its stdout it gets killed with SIGPIPE because the reader of the pipe terminated and so on, effectively killing all processes involved in the shell pipe. And this is why the signal has word pipe in its name.


Normally people ignore SIGPIPE completely when doing TCP:

// Early in main().
signal(SIGPIPE, SIG_IGN);

And/or:

ssize_t rc = send(..., MSG_NOSIGNAL);
if(rc == -1)
    // errno can be EPIPE

This way your just deal with error from send and errno is set to EPIPE.

When SIGPIPE is ignored it is not necessary to use MSG_NOSIGNAL, but it is still good practice, IMO.

Advertisement