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