From 03d50fbd77481568bb2127d8b92e22d2cdc61ab8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Apr 2009 03:05:39 +0200 Subject: sysdeps-unix: if MSG_NOSIGNAL is available don't touch SIGPIPE by default If we can use MSG_NOSIGNAL we don't have to play games with SIGPIPE --- dbus/dbus-connection.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'dbus/dbus-connection.c') diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 947c0afe..afa0ca6a 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -223,7 +223,11 @@ struct DBusPreallocatedSend DBusList *counter_link; /**< Preallocated link in the resource counter */ }; +#ifdef HAVE_DECL_MSG_NOSIGNAL +static dbus_bool_t _dbus_modify_sigpipe = FALSE; +#else static dbus_bool_t _dbus_modify_sigpipe = TRUE; +#endif /** * Implementation details of DBusConnection. All fields are private. -- cgit From 08e49d9b53b675ee2292ac35173dfb4ab97e8d13 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Apr 2009 03:56:18 +0200 Subject: unix-fd: introduce dbus_connection_can_send_type() This is just a wrapper around _dbus_transport_can_pass_unix_fd() however it is more generic. The reason for keeping this generic is to ease later addition of more types without having to add a new API for that. --- dbus/dbus-connection.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) (limited to 'dbus/dbus-connection.c') diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index afa0ca6a..fc872bc2 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -33,6 +33,7 @@ #include "dbus-list.h" #include "dbus-hash.h" #include "dbus-message-internal.h" +#include "dbus-message-private.h" #include "dbus-threads.h" #include "dbus-protocol.h" #include "dbus-dataslot.h" @@ -41,6 +42,7 @@ #include "dbus-object-tree.h" #include "dbus-threads-internal.h" #include "dbus-bus.h" +#include "dbus-marshal-basic.h" #ifdef DBUS_DISABLE_CHECKS #define TOOK_LOCK_CHECK(connection) @@ -2932,14 +2934,58 @@ dbus_connection_get_server_id (DBusConnection *connection) char *id; _dbus_return_val_if_fail (connection != NULL, NULL); - + CONNECTION_LOCK (connection); id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport)); CONNECTION_UNLOCK (connection); - + return id; } +/** + * Tests whether a certain type can be send via the connection. This + * will always return TRUE for all types, with the exception of + * DBUS_TYPE_UNIX_FD. The function will return TRUE for + * DBUS_TYPE_UNIX_FD only on systems that know Unix file descriptors + * and can send them via the chosen transport and when the remote side + * supports this. + * + * This function can be used to do runtime checking for types that + * might be unknown to the specific D-Bus client implementation + * version, i.e. it will return FALSE for all types this + * implementation does not know. + * + * @param connection the connection + * @param type the type to check + * @returns TRUE if the type may be send via the connection + */ +dbus_bool_t +dbus_connection_can_send_type(DBusConnection *connection, + int type) +{ + _dbus_return_val_if_fail (connection != NULL, FALSE); + + if (!_dbus_type_is_valid(type)) + return FALSE; + + if (type != DBUS_TYPE_UNIX_FD) + return TRUE; + +#ifdef HAVE_UNIX_FD_PASSING + { + dbus_bool_t b; + + CONNECTION_LOCK(connection); + b = _dbus_transport_can_pass_unix_fd(connection->transport); + CONNECTION_UNLOCK(connection); + + return b; + } +#endif + + return FALSE; +} + /** * Set whether _exit() should be called when the connection receives a * disconnect signal. The call to _exit() comes after any handlers for -- cgit From 2eb14dbcac1870dda1b36ce1e6fedfe7500572cb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Apr 2009 04:01:01 +0200 Subject: unix-fd: when sending a message with unix fds verify that the connection can do it Not all of the send function flavours allow returning proper error codes. For the cases where this is not easily possible the client should call dbus_connection_can_send_type() first. --- dbus/dbus-connection.c | 76 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 7 deletions(-) (limited to 'dbus/dbus-connection.c') diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index fc872bc2..8433b643 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -3086,8 +3086,23 @@ dbus_connection_send_preallocated (DBusConnection *connection, _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL || (dbus_message_get_interface (message) != NULL && dbus_message_get_member (message) != NULL)); - + CONNECTION_LOCK (connection); + +#ifdef HAVE_UNIX_FD_PASSING + + if (!_dbus_transport_can_pass_unix_fd(connection->transport) && + message->n_unix_fds > 0) + { + /* Refuse to send fds on a connection that cannot handle + them. Unfortunately we cannot return a proper error here, so + the best we can is just return. */ + CONNECTION_UNLOCK (connection); + return; + } + +#endif + _dbus_connection_send_preallocated_and_unlock (connection, preallocated, message, client_serial); @@ -3151,6 +3166,20 @@ dbus_connection_send (DBusConnection *connection, CONNECTION_LOCK (connection); +#ifdef HAVE_UNIX_FD_PASSING + + if (!_dbus_transport_can_pass_unix_fd(connection->transport) && + message->n_unix_fds > 0) + { + /* Refuse to send fds on a connection that cannot handle + them. Unfortunately we cannot return a proper error here, so + the best we can is just return. */ + CONNECTION_UNLOCK (connection); + return FALSE; + } + +#endif + return _dbus_connection_send_and_unlock (connection, message, serial); @@ -3207,12 +3236,16 @@ reply_handler_timeout (void *data) * timeout to mean "very long timeout." libdbus clamps an INT_MAX * timeout down to a few hours timeout though. * - * @warning if the connection is disconnected, the #DBusPendingCall - * will be set to #NULL, so be careful with this. - * + * @warning if the connection is disconnected or you try to send Unix + * file descriptors on a connection that does not support them, the + * #DBusPendingCall will be set to #NULL, so be careful with this. + * * @param connection the connection * @param message the message to send - * @param pending_return return location for a #DBusPendingCall object, or #NULL if connection is disconnected + * @param pending_return return location for a #DBusPendingCall + * object, or #NULL if connection is disconnected or when you try to + * send Unix file descriptors on a connection that does not support + * them. * @param timeout_milliseconds timeout in milliseconds or -1 for default * @returns #FALSE if no memory, #TRUE otherwise. * @@ -3236,6 +3269,21 @@ dbus_connection_send_with_reply (DBusConnection *connection, CONNECTION_LOCK (connection); +#ifdef HAVE_UNIX_FD_PASSING + + if (!_dbus_transport_can_pass_unix_fd(connection->transport) && + message->n_unix_fds > 0) + { + /* Refuse to send fds on a connection that cannot handle + them. Unfortunately we cannot return a proper error here, so + the best we can do is return TRUE but leave *pending_return + as NULL. */ + CONNECTION_UNLOCK (connection); + return TRUE; + } + +#endif + if (!_dbus_connection_get_is_connected_unlocked (connection)) { CONNECTION_UNLOCK (connection); @@ -3344,12 +3392,26 @@ dbus_connection_send_with_reply_and_block (DBusConnection *connection, { DBusMessage *reply; DBusPendingCall *pending; - + _dbus_return_val_if_fail (connection != NULL, NULL); _dbus_return_val_if_fail (message != NULL, NULL); _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL); _dbus_return_val_if_error_is_set (error, NULL); - + +#ifdef HAVE_UNIX_FD_PASSING + + CONNECTION_LOCK (connection); + if (!_dbus_transport_can_pass_unix_fd(connection->transport) && + message->n_unix_fds > 0) + { + CONNECTION_UNLOCK (connection); + dbus_set_error(error, DBUS_ERROR_FAILED, "Cannot send file descriptors on this connection."); + return NULL; + } + CONNECTION_UNLOCK (connection); + +#endif + if (!dbus_connection_send_with_reply (connection, message, &pending, timeout_milliseconds)) { -- cgit From bfad32422f1f78bce4de1e88a4afb5cc295bb877 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 20 May 2009 01:32:46 +0200 Subject: unix-fd: add logic to count unix fds the same way as allocated memory This make all counters count both bytes of memory and unix fds. --- dbus/dbus-connection.c | 119 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 110 insertions(+), 9 deletions(-) (limited to 'dbus/dbus-connection.c') diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 8433b643..e46fbc3d 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -627,8 +627,8 @@ _dbus_connection_message_sent (DBusConnection *connection, connection, connection->n_outgoing); /* Save this link in the link cache also */ - _dbus_message_remove_size_counter (message, connection->outgoing_counter, - &link); + _dbus_message_remove_counter (message, connection->outgoing_counter, + &link); _dbus_list_prepend_link (&connection->link_cache, link); dbus_message_unref (message); @@ -1922,8 +1922,8 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *con _dbus_list_prepend_link (&connection->outgoing_messages, preallocated->queue_link); - _dbus_message_add_size_counter_link (message, - preallocated->counter_link); + _dbus_message_add_counter_link (message, + preallocated->counter_link); dbus_free (preallocated); preallocated = NULL; @@ -2539,9 +2539,9 @@ free_outgoing_message (void *element, DBusMessage *message = element; DBusConnection *connection = data; - _dbus_message_remove_size_counter (message, - connection->outgoing_counter, - NULL); + _dbus_message_remove_counter (message, + connection->outgoing_counter, + NULL); dbus_message_unref (message); } @@ -5931,6 +5931,45 @@ dbus_connection_get_max_message_size (DBusConnection *connection) return res; } +/** + * Specifies the maximum number of unix fds a message on this + * connection is allowed to receive. Messages with more unix fds will + * result in disconnecting the connection. + * + * @param connection a #DBusConnection + * @param size maximum message unix fds the connection can receive + */ +void +dbus_connection_set_max_message_unix_fds (DBusConnection *connection, + long n) +{ + _dbus_return_if_fail (connection != NULL); + + CONNECTION_LOCK (connection); + _dbus_transport_set_max_message_unix_fds (connection->transport, + n); + CONNECTION_UNLOCK (connection); +} + +/** + * Gets the value set by dbus_connection_set_max_message_unix_fds(). + * + * @param connection the connection + * @returns the max numer of unix fds of a single message + */ +long +dbus_connection_get_max_message_unix_fds (DBusConnection *connection) +{ + long res; + + _dbus_return_val_if_fail (connection != NULL, 0); + + CONNECTION_LOCK (connection); + res = _dbus_transport_get_max_message_unix_fds (connection->transport); + CONNECTION_UNLOCK (connection); + return res; +} + /** * Sets the maximum total number of bytes that can be used for all messages * received on this connection. Messages count toward the maximum until @@ -5987,6 +6026,48 @@ dbus_connection_get_max_received_size (DBusConnection *connection) return res; } +/** + * Sets the maximum total number of unix fds that can be used for all messages + * received on this connection. Messages count toward the maximum until + * they are finalized. When the maximum is reached, the connection will + * not read more data until some messages are finalized. + * + * The semantics are analogous to those of dbus_connection_set_max_received_size(). + * + * @param connection the connection + * @param size the maximum size in bytes of all outstanding messages + */ +void +dbus_connection_set_max_received_unix_fds (DBusConnection *connection, + long n) +{ + _dbus_return_if_fail (connection != NULL); + + CONNECTION_LOCK (connection); + _dbus_transport_set_max_received_unix_fds (connection->transport, + n); + CONNECTION_UNLOCK (connection); +} + +/** + * Gets the value set by dbus_connection_set_max_received_unix_fds(). + * + * @param connection the connection + * @returns the max unix fds of all live messages + */ +long +dbus_connection_get_max_received_unix_fds (DBusConnection *connection) +{ + long res; + + _dbus_return_val_if_fail (connection != NULL, 0); + + CONNECTION_LOCK (connection); + res = _dbus_transport_get_max_received_unix_fds (connection->transport); + CONNECTION_UNLOCK (connection); + return res; +} + /** * Gets the approximate size in bytes of all messages in the outgoing * message queue. The size is approximate in that you shouldn't use @@ -6003,9 +6084,29 @@ dbus_connection_get_outgoing_size (DBusConnection *connection) long res; _dbus_return_val_if_fail (connection != NULL, 0); - + + CONNECTION_LOCK (connection); + res = _dbus_counter_get_size_value (connection->outgoing_counter); + CONNECTION_UNLOCK (connection); + return res; +} + +/** + * Gets the approximate number of uni fds of all messages in the + * outgoing message queue. + * + * @param connection the connection + * @returns the number of unix fds that have been queued up but not sent + */ +long +dbus_connection_get_outgoing_unix_fds (DBusConnection *connection) +{ + long res; + + _dbus_return_val_if_fail (connection != NULL, 0); + CONNECTION_LOCK (connection); - res = _dbus_counter_get_value (connection->outgoing_counter); + res = _dbus_counter_get_unix_fd_value (connection->outgoing_counter); CONNECTION_UNLOCK (connection); return res; } -- cgit