From 5863f7907e3dab17e09b4e8d30eb751cb638ae19 Mon Sep 17 00:00:00 2001 From: "Mario J. Rugiero" Date: Fri, 5 Jul 2019 05:20:59 -0300 Subject: [PATCH] Take ownership of the well-known D-Bus name synchronously. --- src/appfinder-gdbus.c | 82 ++++++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 29 deletions(-) diff --git a/src/appfinder-gdbus.c b/src/appfinder-gdbus.c index 4ab342d..b49d774 100644 --- a/src/appfinder-gdbus.c +++ b/src/appfinder-gdbus.c @@ -104,15 +104,55 @@ static const GDBusInterfaceVTable appfinder_gdbus_vtable = -static void -appfinder_gdbus_bus_acquired (GDBusConnection *connection, - const gchar *name, - gpointer user_data) +gboolean +appfinder_gdbus_service (GError **error) { - guint register_id; - GDBusNodeInfo *info; - GError *error = NULL; + GDBusConnection *connection; + guint32 request_name_reply; + GVariant *params = g_variant_new ("(su)", + APPFINDER_DBUS_SERVICE, + G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE); + GVariant *result; + guint register_id; + GDBusNodeInfo *info; + + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error); + if (G_UNLIKELY (connection == NULL)) + return FALSE; + + /* The g_bus_* API doesn't provide the means for synchronously owning a name. */ + result = g_dbus_connection_call_sync (connection, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "RequestName", + params, + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + error); + + if (!result) + { + g_message ("Failed to request name: %s", (*error)->message); + g_error_free (*error); + g_object_unref (connection); + return FALSE; + } + + g_variant_get (result, "(u)", &request_name_reply); + g_variant_unref (result); + /* There's already another server up. */ + /* 1 == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER, i.e. we got it. */ + if (request_name_reply != 1) + { + g_object_unref (connection); + return FALSE; + } + + /* We're the server, let's start serving! */ info = g_dbus_node_info_new_for_xml (appfinder_gdbus_introspection_xml, NULL); g_assert (info != NULL); g_assert (*info->interfaces != NULL); @@ -121,38 +161,22 @@ appfinder_gdbus_bus_acquired (GDBusConnection *connection, APPFINDER_DBUS_PATH, *info->interfaces, /* first iface */ &appfinder_gdbus_vtable, - user_data, NULL, - &error); + NULL, + error); APPFINDER_DEBUG ("registered interface with id %d", register_id); if (register_id == 0) { - g_message ("Failed to register object: %s", error->message); - g_error_free (error); + g_message ("Failed to register object: %s", (*error)->message); + g_error_free (*error); } g_dbus_node_info_unref (info); -} - - -gboolean -appfinder_gdbus_service (GError **error) -{ - guint owner_id; - - owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, - APPFINDER_DBUS_SERVICE, - G_BUS_NAME_OWNER_FLAGS_NONE, - appfinder_gdbus_bus_acquired, - NULL, - NULL, - NULL, - NULL); - - return (owner_id != 0); + /* N.B.: leaks the connection on purpose. */ + return TRUE; } -- 2.20.1