d760ebeab2
Resolves: #1631998
87 lines
2.7 KiB
Diff
87 lines
2.7 KiB
Diff
From 23e01e9a966ee0aa08668a75f5753a55e1ea4547 Mon Sep 17 00:00:00 2001
|
|
From: Robbie Harwood <rharwood@redhat.com>
|
|
Date: Fri, 12 Oct 2018 16:57:05 -0400
|
|
Subject: [PATCH] Prevent SIGPIPE from socket writes on UNIX-likes
|
|
|
|
When writing to a disconnected socket, try to only get EPIPE rather
|
|
than taking down the process with SIGPIPE.
|
|
|
|
On recent Linux and other systems which have it, switch from writev to
|
|
sendmsg and pass MSG_NOSIGNAL.
|
|
|
|
On BSD-likes, set SO_NOSIGPIPE at connect time.
|
|
|
|
ticket: 8753 (new)
|
|
(cherry picked from commit 98bf22027bd6e746f456a671ca5e257ca4bd371e)
|
|
---
|
|
src/include/port-sockets.h | 43 +++++++++++++++++++++++++++++++++++---
|
|
1 file changed, 40 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/src/include/port-sockets.h b/src/include/port-sockets.h
|
|
index b3ab9c906..3b05e022d 100644
|
|
--- a/src/include/port-sockets.h
|
|
+++ b/src/include/port-sockets.h
|
|
@@ -158,6 +158,7 @@ typedef int socklen_t;
|
|
#include <netinet/in.h> /* For struct sockaddr_in and in_addr */
|
|
#include <arpa/inet.h> /* For inet_ntoa */
|
|
#include <netdb.h>
|
|
+#include <string.h> /* For memset */
|
|
|
|
#ifndef HAVE_NETDB_H_H_ERRNO
|
|
extern int h_errno; /* In case it's missing, e.g., HP-UX 10.20. */
|
|
@@ -218,15 +219,51 @@ typedef struct iovec sg_buf;
|
|
#define SOCKET_NFDS(f) ((f)+1) /* select() arg for a single fd */
|
|
#define SOCKET_READ read
|
|
#define SOCKET_WRITE write
|
|
-#define SOCKET_CONNECT connect
|
|
+static inline int
|
|
+socket_connect(int fd, const struct sockaddr *addr, socklen_t addrlen)
|
|
+{
|
|
+ int st;
|
|
+#ifdef SO_NOSIGPIPE
|
|
+ int set = 1;
|
|
+#endif
|
|
+
|
|
+ st = connect(fd, addr, addrlen);
|
|
+ if (st == -1)
|
|
+ return st;
|
|
+
|
|
+#ifdef SO_NOSIGPIPE
|
|
+ st = setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &set, sizeof(set));
|
|
+ if (st != 0)
|
|
+ st = -1;
|
|
+#endif
|
|
+
|
|
+ return st;
|
|
+}
|
|
+#define SOCKET_CONNECT socket_connect
|
|
#define SOCKET_GETSOCKNAME getsockname
|
|
#define SOCKET_CLOSE close
|
|
#define SOCKET_EINTR EINTR
|
|
#define SOCKET_WRITEV_TEMP int
|
|
+static inline ssize_t
|
|
+socket_sendmsg(SOCKET fd, sg_buf *iov, int iovcnt)
|
|
+{
|
|
+ struct msghdr msg;
|
|
+ int flags = 0;
|
|
+
|
|
+#ifdef MSG_NOSIGNAL
|
|
+ flags |= MSG_NOSIGNAL;
|
|
+#endif
|
|
+
|
|
+ memset(&msg, 0, sizeof(msg));
|
|
+ msg.msg_iov = iov;
|
|
+ msg.msg_iovlen = iovcnt;
|
|
+
|
|
+ return sendmsg(fd, &msg, flags);
|
|
+}
|
|
/* Use TMP to avoid compiler warnings and keep things consistent with
|
|
* Windows version. */
|
|
-#define SOCKET_WRITEV(FD, SG, LEN, TMP) \
|
|
- ((TMP) = writev((FD), (SG), (LEN)), (TMP))
|
|
+#define SOCKET_WRITEV(FD, SG, LEN, TMP) \
|
|
+ ((TMP) = socket_sendmsg((FD), (SG), (LEN)), (TMP))
|
|
|
|
#define SHUTDOWN_READ 0
|
|
#define SHUTDOWN_WRITE 1
|