How to prevent SIGPIPE or prevent the server from ending?

c, c++, client-server, signals, sockets

Solution

Did you by any chance not do the `signal` ignore prior to spawning off any threads? If you waited until later one of the other threads could still pick up the signal and exit your app.

If that doesn't do it, you can always do a write `poll`/`select` before trying the write to make sure the socket is writable.

Problem

A quite standard C++ TCP server program using pthreads, bind, listen and accept. I have the scenario that the server ends (read: crashes) when I kill a connected client. The reason for the crash is that the `write()` call on the file fails, thus the program receives a SIGPIPE. And I guess, this makes the server exit. I thought, "of course, unhandled signal means exit", so let's use `signal()`: ``` signal(SIGPIPE, SIG_IGN); ``` because, taken from `man 2 write`: EPIPE fd is connected to a pipe or socket whose reading end is closed. When this happens the writing process will also receive a SIGPIPE signal. (Thus, the write return value is seen only if the program catches, blocks or ignores this signal.) Alas, no. Neither in the server thread nor the client threads does this seem to help. So, how do I prevent the `write()` call from raising that signal, or (to be pragmatic) how do I stop the server from exiting. My diagnostics are: - server thread started, binding, listening, accepting. - let a client connect (via telnet for example) - send a `pkill telnet` to crash the client unwanted behavior: server exits, in gdb with ``` ... in write () at ../sysdeps/unix/syscall-template.S:82 82 T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS) ``` and the backtrace: ``` #0 ... in write () at ../sysdeps/unix/syscall-template.S:82 #1 ... in ClientHandler::mesg(std::string) () #2 ... in ClientHandler::handle() () #3 ... in start_thread (arg=<value optimized out>) at pthread_create.c:300 #4 ... in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112 #5 ... in ?? () ```

Original source