diff --git a/bus/connection.c b/bus/connection.c index add1c8b8..95bc6c0a 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -2374,6 +2374,21 @@ bus_transaction_send_from_driver (BusTransaction *transaction, if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS)) return FALSE; + /* Make sure the message has a non-zero serial number, otherwise + * bus_transaction_capture_error_reply() will not be able to mock up + * a corresponding reply for it. Normally this would be delayed until + * the first time we actually send the message out from a + * connection, when the transaction is committed, but that's too late + * in this case. + */ + if (dbus_message_get_serial (message) == 0) + { + dbus_uint32_t next_serial; + + next_serial = _dbus_connection_get_next_client_serial (connection); + dbus_message_set_serial (message, next_serial); + } + if (bus_connection_is_active (connection)) { if (!dbus_message_set_destination (message, diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h index d6947d18..df3c7010 100644 --- a/dbus/dbus-connection-internal.h +++ b/dbus/dbus-connection-internal.h @@ -55,6 +55,8 @@ DBUS_PRIVATE_EXPORT DBusConnection * _dbus_connection_ref_unlocked (DBusConnection *connection); DBUS_PRIVATE_EXPORT void _dbus_connection_unref_unlocked (DBusConnection *connection); +DBUS_PRIVATE_EXPORT +dbus_uint32_t _dbus_connection_get_next_client_serial (DBusConnection *connection); void _dbus_connection_queue_received_message_link (DBusConnection *connection, DBusList *link); dbus_bool_t _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection); diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index a61e56a6..e6fedbbe 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -1459,7 +1459,16 @@ _dbus_connection_unref_unlocked (DBusConnection *connection) _dbus_connection_last_unref (connection); } -static dbus_uint32_t +/** + * Allocate and return the next non-zero serial number for outgoing messages. + * + * This method is only valid to call from single-threaded code, such as + * the dbus-daemon, or with the connection lock held. + * + * @param connection the connection + * @returns A suitable serial number for the next message to be sent on the connection. + */ +dbus_uint32_t _dbus_connection_get_next_client_serial (DBusConnection *connection) { dbus_uint32_t serial;