diff options
author | Lennart Poettering <lennart@poettering.net> | 2009-04-22 02:54:23 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2009-05-15 20:30:15 +0200 |
commit | ff0a8993d4716cb7729f4a0ffab9ab242f82b242 (patch) | |
tree | 16b1581f7ed9175db9d42733a1b7507bf7bf9296 | |
parent | 6d2eacba89328029891ffe774ce37df44387cfbb (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.c | 61 |
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 } |