krb5 commit: Prevent SIGPIPE from socket writes on UNIX-likes
Greg Hudson
ghudson at mit.edu
Wed Oct 17 15:23:06 EDT 2018
https://github.com/krb5/krb5/commit/98bf22027bd6e746f456a671ca5e257ca4bd371e
commit 98bf22027bd6e746f456a671ca5e257ca4bd371e
Author: Robbie Harwood <rharwood at redhat.com>
Date: Fri Oct 12 16:57:05 2018 -0400
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)
src/include/port-sockets.h | 43 ++++++++++++++++++++++++++++++++++++++++---
1 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/src/include/port-sockets.h b/src/include/port-sockets.h
index f0fc2b8..57e5d1d 100644
--- a/src/include/port-sockets.h
+++ b/src/include/port-sockets.h
@@ -159,6 +159,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. */
@@ -219,15 +220,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
More information about the cvs-krb5
mailing list