If the server hangs up while we are writing, we'd rather have send()
fail with EPIPE than deal with a SIGPIPE signal - especially when we
are being run as a library inside a larger program that may have other
intentions on what signals should do for its other activities. At
least Linux makes this easy with the MSG_NOSIGNAL flag (it requires
that we use send() instead of write(), which in turn requires
socketpair() rather than pipe() for nbd_connect_command - but we
already do that). If we ever branch out into accepting pre-opened
fds, we'll have to deal with SIGPIPE suppression for non-sockets at
that time.
---
lib/socket.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/lib/socket.c b/lib/socket.c
index 8555855..a0f3d61 100644
--- a/lib/socket.c
+++ b/lib/socket.c
@@ -46,6 +46,13 @@ socket_send (struct nbd_handle *h,
{
ssize_t r;
+ /* We don't want to die from SIGPIPE, but also don't want to force a
+ * changed signal handler on the rest of the application.
+ */
+#ifdef MSG_NOSIGNAL
+ flags |= MSG_NOSIGNAL;
+#endif
+
r = send (sock->u.fd, buf, len, flags);
if (r == -1 && errno != EAGAIN && errno != EWOULDBLOCK)
set_error (errno, "send");
--
2.20.1