From 214ff374545f433076515d80134dca7a1cdb991e Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 29 Nov 2012 16:20:03 +0000 Subject: [PATCH 6/6] Produce fake NameOwnerChanged signals that encode the pid of each peer --- bus/driver.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/bus/driver.c b/bus/driver.c index 574e0f3..bc0a86b 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -241,6 +241,78 @@ create_unique_client_name (BusRegistry *registry, return TRUE; } +#ifdef DBUS_ENABLE_CAPTURE +static dbus_bool_t +bus_driver_capture_pid (DBusConnection *connection, + BusTransaction *transaction) +{ + DBusMessage *lie = NULL; + DBusString pid_name_buffer; + const char *pid_name; + const char *empty_name = ""; + const char *unique_name; + unsigned long pid; + + /* This is an entertaining hack suggested by the illustrious wjt. + * To profile a boot process or login, we want Bustle to show us process + * IDs. What it actually shows us are all our bus names. So... pretend + * the process had a bus name that contains its process ID. */ + + if (!dbus_connection_get_unix_process_id (connection, &pid)) + { + /* Nothing useful we can do here. Do nothing, successfully. */ + return TRUE; + } + + if (!_dbus_string_init (&pid_name_buffer)) + return FALSE; + + lie = dbus_message_new_signal (DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, + "NameOwnerChanged"); + + if (lie == NULL) + goto oom; + + if (!dbus_message_set_sender (lie, DBUS_SERVICE_DBUS)) + goto oom; + + if (!_dbus_string_append_printf (&pid_name_buffer, + "org.freedesktop.DBus.PcapHack.Process%lu", + pid)) + goto oom; + + pid_name = _dbus_string_get_const_data (&pid_name_buffer); + + unique_name = bus_connection_get_name (connection); + + if (!dbus_message_append_args (lie, + DBUS_TYPE_STRING, &pid_name, + DBUS_TYPE_STRING, &empty_name, + DBUS_TYPE_STRING, &unique_name, + DBUS_TYPE_INVALID)) + goto oom; + + _dbus_assert (dbus_message_has_signature (lie, "sss")); + + /* Include the message in the transaction as if it had been sent, but do + * not actually send it. */ + if (!bus_transaction_capture (transaction, lie)) + goto oom; + + _dbus_string_free (&pid_name_buffer); + dbus_message_unref (lie); + return TRUE; + + oom: + if (lie != NULL) + dbus_message_unref (lie); + + _dbus_string_free (&pid_name_buffer); + + return FALSE; +} +#endif + static dbus_bool_t bus_driver_handle_hello (DBusConnection *connection, BusTransaction *transaction, @@ -315,6 +387,16 @@ bus_driver_handle_hello (DBusConnection *connection, if (service == NULL) goto out_0; +#ifdef DBUS_ENABLE_CAPTURE + /* This needs to happen after bus_registry_ensure() so the fake well-known + * name only appears after the unique name. */ + if (!bus_driver_capture_pid (connection, transaction)) + { + BUS_SET_OOM (error); + goto out_0; + } +#endif + _dbus_assert (bus_connection_is_active (connection)); retval = TRUE; -- 1.7.10.4