From ff0a8993d4716cb7729f4a0ffab9ab242f82b242 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Apr 2009 02:54:23 +0200 Subject: 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. --- dbus/dbus-sysdeps-unix.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'dbus') 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 } -- cgit