On Sun, 22 Dec 2019 16:10:15 +0300 Valery Ushakov <[email protected]> wrote:
> Of course since you are writing a networking server you DO want to be > notifed about send() errors and SIGPIPE gets in the way. So you can > tell the kernel, "hey, I know what I'm doing, I will handle this > myself". I don't remember off hand which OS has which of these flags, > but there're > > SOCK_NOSIGPIPE - can be or-ed into the type argument of socket(2) > SO_NOSIGPIPE - SOL_SOCKET level socket option > MSG_NOSIGNAL - send(2) flag > This is the problem, I'm trying to deal with various idiosyncrasies of sockets APIs. In order for the code to be portable and behave correctly across various platforms, you need to be aware of such issues, but it's not always obvious from the man pages. Also different platforms have different ways of dealing with SIGPIPE, i.e. Linux and BSD have MSG_NOSIGNAL for send(), Solaris instead has SO_NOSIGPIPE for setsockopt(), etc. The most portable way seems to be to set a signal handler to ignore SIGPIPE. What I don't understand is when the other end of TCP connection sends RST, performing a send() on a socket sometimes results in ECONNRESET and sometimes in SIGPIPE. Why? As I mentioned previously, I was under the impression that SIGPIPE was sent only after send() returned -1 with errno set to ECONNRESET and you then call send() again on this socket. But this is not what I was seeing on NetBSD. https://stackoverflow.com/questions/33053507/econnreset-in-send-linux-c Reading comments on stackoverflow, some people state that ECONNRESET is returned when RST arrived while some of the data from send() was in-flight and might have been lost. And SIGPIPE is sent when RST arrived while all of the previously sent data was acknowledged by TCP and there was no data loss. I'm not sure if this is universally true across all platforms or not. The whole idea of SIGPIPE for sockets seems like huge mistake and just adds to confusion and potential to introducing bugs which terminate your process when this signal is not handled. But, this is ancient history and that is how Unix was designed. I just wanted to understand ECONNRESET vs SIGPIPE for send() syscall.
