socket: avoid SIGPIPE using SO_NOSIGPIPE or MSG_NOSIGNAL
diff --git a/src/socket.c b/src/socket.c index c35de33..fe7d06c 100644 --- a/src/socket.c +++ b/src/socket.c
@@ -55,6 +55,7 @@ struct sockaddr_un name; int sock; size_t size; + int yes = 1; // remove if still present unlink(filename); @@ -66,6 +67,14 @@ return -1; } +#ifdef SO_NOSIGPIPE + if (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (void*)&yes, sizeof(int)) == -1) { + perror("setsockopt()"); + socket_close(sock); + return -1; + } +#endif + /* Bind a name to the socket. */ name.sun_family = AF_LOCAL; strncpy(name.sun_path, filename, sizeof(name.sun_path)); @@ -102,6 +111,7 @@ int sfd = -1; size_t size; struct stat fst; + int yes = 1; // check if socket file exists... if (stat(filename, &fst) != 0) { @@ -123,6 +133,15 @@ fprintf(stderr, "%s: socket: %s\n", __func__, strerror(errno)); return -1; } + +#ifdef SO_NOSIGPIPE + if (setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&yes, sizeof(int)) == -1) { + perror("setsockopt()"); + socket_close(sfd); + return -1; + } +#endif + // and connect to 'filename' name.sun_family = AF_LOCAL; strncpy(name.sun_path, filename, sizeof(name.sun_path)); @@ -170,6 +189,14 @@ return -1; } +#ifdef SO_NOSIGPIPE + if (setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&yes, sizeof(int)) == -1) { + perror("setsockopt()"); + socket_close(sfd); + return -1; + } +#endif + memset((void *) &saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); @@ -236,6 +263,14 @@ return -1; } +#ifdef SO_NOSIGPIPE + if (setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&yes, sizeof(int)) == -1) { + perror("setsockopt()"); + socket_close(sfd); + return -1; + } +#endif + memset((void *) &saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = *(uint32_t *) hp->h_addr; @@ -388,5 +423,9 @@ int socket_send(int fd, void *data, size_t length) { - return send(fd, data, length, 0); + int flags = 0; +#ifdef MSG_NOSIGNAL + flags |= MSG_NOSIGNAL; +#endif + return send(fd, data, length, flags); }