diff options
Diffstat (limited to 'dbus/dbus-transport-socket.c')
-rw-r--r-- | dbus/dbus-transport-socket.c | 109 |
1 files changed, 85 insertions, 24 deletions
diff --git a/dbus/dbus-transport-socket.c b/dbus/dbus-transport-socket.c index 8be4d135..4b88af7c 100644 --- a/dbus/dbus-transport-socket.c +++ b/dbus/dbus-transport-socket.c @@ -28,7 +28,6 @@ #include "dbus-watch.h" #include "dbus-credentials.h" - /** * @defgroup DBusTransportSocket DBusTransport implementations for sockets * @ingroup DBusInternals @@ -192,7 +191,8 @@ check_read_watch (DBusTransport *transport) if (_dbus_transport_get_is_authenticated (transport)) need_read_watch = - _dbus_counter_get_value (transport->live_messages_size) < transport->max_live_messages_size; + (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) && + (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds); else { if (transport->receive_credentials_pending) @@ -551,6 +551,9 @@ do_writing (DBusTransport *transport) if (_dbus_auth_needs_encoding (transport->auth)) { + /* Does fd passing even make sense with encoded data? */ + _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport)); + if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0) { if (!_dbus_auth_encode_data (transport->auth, @@ -588,27 +591,53 @@ do_writing (DBusTransport *transport) #if 0 _dbus_verbose ("message is %d bytes\n", - total_bytes_to_write); + total_bytes_to_write); #endif - - if (socket_transport->message_bytes_written < header_len) + +#ifdef HAVE_UNIX_FD_PASSING + if (socket_transport->message_bytes_written <= 0 && DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport)) { + /* Send the fds along with the first byte of the message */ + const int *unix_fds; + unsigned n; + + _dbus_message_get_unix_fds(message, &unix_fds, &n); + bytes_written = - _dbus_write_socket_two (socket_transport->fd, - header, - socket_transport->message_bytes_written, - header_len - socket_transport->message_bytes_written, - body, - 0, body_len); + _dbus_write_socket_with_unix_fds_two (socket_transport->fd, + header, + socket_transport->message_bytes_written, + header_len - socket_transport->message_bytes_written, + body, + 0, body_len, + unix_fds, + n); + + if (bytes_written > 0 && n > 0) + _dbus_verbose("Wrote %i unix fds\n", n); } else +#endif { - bytes_written = - _dbus_write_socket (socket_transport->fd, - body, - (socket_transport->message_bytes_written - header_len), - body_len - - (socket_transport->message_bytes_written - header_len)); + if (socket_transport->message_bytes_written < header_len) + { + bytes_written = + _dbus_write_socket_two (socket_transport->fd, + header, + socket_transport->message_bytes_written, + header_len - socket_transport->message_bytes_written, + body, + 0, body_len); + } + else + { + bytes_written = + _dbus_write_socket (socket_transport->fd, + body, + (socket_transport->message_bytes_written - header_len), + body_len - + (socket_transport->message_bytes_written - header_len)); + } } } @@ -704,6 +733,9 @@ do_reading (DBusTransport *transport) if (_dbus_auth_needs_decoding (transport->auth)) { + /* Does fd passing even make sense with encoded data? */ + _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport)); + if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0) bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming); else @@ -748,10 +780,37 @@ do_reading (DBusTransport *transport) { _dbus_message_loader_get_buffer (transport->loader, &buffer); - - bytes_read = _dbus_read_socket (socket_transport->fd, - buffer, socket_transport->max_bytes_read_per_iteration); - + +#ifdef HAVE_UNIX_FD_PASSING + if (DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport)) + { + int *fds, n_fds; + + if (!_dbus_message_loader_get_unix_fds(transport->loader, &fds, &n_fds)) + { + _dbus_verbose ("Out of memory reading file descriptors\n"); + _dbus_message_loader_return_buffer (transport->loader, buffer, 0); + oom = TRUE; + goto out; + } + + bytes_read = _dbus_read_socket_with_unix_fds(socket_transport->fd, + buffer, + socket_transport->max_bytes_read_per_iteration, + fds, &n_fds); + + if (bytes_read >= 0 && n_fds > 0) + _dbus_verbose("Read %i unix fds\n", n_fds); + + _dbus_message_loader_return_unix_fds(transport->loader, fds, bytes_read < 0 ? 0 : n_fds); + } + else +#endif + { + bytes_read = _dbus_read_socket (socket_transport->fd, + buffer, socket_transport->max_bytes_read_per_iteration); + } + _dbus_message_loader_return_buffer (transport->loader, buffer, bytes_read < 0 ? 0 : bytes_read); @@ -1204,7 +1263,11 @@ _dbus_transport_new_for_socket (int fd, &socket_vtable, server_guid, address)) goto failed_4; - + +#ifdef HAVE_UNIX_FD_PASSING + _dbus_auth_set_unix_fd_possible(socket_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd)); +#endif + socket_transport->fd = fd; socket_transport->message_bytes_written = 0; @@ -1282,8 +1345,6 @@ _dbus_transport_new_for_tcp_socket (const char *host, return NULL; } - _dbus_fd_set_close_on_exec (fd); - _dbus_verbose ("Successfully connected to tcp socket %s:%s\n", host, port); |