summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2009-04-22 02:54:23 +0200
committerLennart Poettering <lennart@poettering.net>2009-05-15 20:30:15 +0200
commitff0a8993d4716cb7729f4a0ffab9ab242f82b242 (patch)
tree16b1581f7ed9175db9d42733a1b7507bf7bf9296
parent6d2eacba89328029891ffe774ce37df44387cfbb (diff)
sysdeps-unix: Use MSG_NOSIGNAL when available
On Linux send()/sendmsg() know the special flag MSG_NOSIGNAL which if set makes sure that no SIGPIPE signal is raised when we write to a socket that has been disconnected. By using this flag we don't have to play games with SIGPIPE which is pretty ugly stuff since it touches the global process context.
-rw-r--r--dbus/dbus-sysdeps-unix.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index 29d234a4..2e129826 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -179,7 +179,24 @@ _dbus_write_socket (int fd,
int start,
int len)
{
+#ifdef MSG_NOSIGNAL
+ const char *data;
+ int bytes_written;
+
+ data = _dbus_string_get_const_data_len (buffer, start, len);
+
+ again:
+
+ bytes_written = send (fd, data, len, MSG_NOSIGNAL);
+
+ if (bytes_written < 0 && errno == EINTR)
+ goto again;
+
+ return bytes_written;
+
+#else
return _dbus_write (fd, buffer, start, len);
+#endif
}
/**
@@ -255,8 +272,52 @@ _dbus_write_socket_two (int fd,
int start2,
int len2)
{
+#ifdef MSG_NOSIGNAL
+ struct iovec vectors[2];
+ const char *data1;
+ const char *data2;
+ int bytes_written;
+ struct msghdr m;
+
+ _dbus_assert (buffer1 != NULL);
+ _dbus_assert (start1 >= 0);
+ _dbus_assert (start2 >= 0);
+ _dbus_assert (len1 >= 0);
+ _dbus_assert (len2 >= 0);
+
+ data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
+
+ if (buffer2 != NULL)
+ data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
+ else
+ {
+ data2 = NULL;
+ start2 = 0;
+ len2 = 0;
+ }
+
+ vectors[0].iov_base = (char*) data1;
+ vectors[0].iov_len = len1;
+ vectors[1].iov_base = (char*) data2;
+ vectors[1].iov_len = len2;
+
+ memset(&m, 0, sizeof(m));
+ m.msg_iov = vectors;
+ m.msg_iovlen = data2 ? 2 : 1;
+
+ again:
+
+ bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
+
+ if (bytes_written < 0 && errno == EINTR)
+ goto again;
+
+ return bytes_written;
+
+#else
return _dbus_write_two (fd, buffer1, start1, len1,
buffer2, start2, len2);
+#endif
}