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.