summaryrefslogtreecommitdiffstats
path: root/dbus
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 /dbus
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.
Diffstat (limited to 'dbus')
-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
}