[glib] gio: Support using GDBusObjectManagerServer at pat h ‘/’



commit b26b083aa20daceeb14ab43a73655d06c9fccf5b
Author: Philip Withnall <philip withnall collabora co uk>
Date:   Wed Feb 10 09:36:16 2016 +0000

    gio: Support using GDBusObjectManagerServer at path ‘/’
    
    Previously this would cause an assertion failure when checking the paths
    of exported objects, as it would try to check that their paths started
    with ‘//’ due to mishandling the root object case.
    
    Includes a unit test.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=761810

 gio/gdbusobjectmanagerserver.c        |   11 ++++++---
 gio/tests/gdbus-peer-object-manager.c |   39 ++++++++++++++++++++++++--------
 2 files changed, 36 insertions(+), 14 deletions(-)
---
diff --git a/gio/gdbusobjectmanagerserver.c b/gio/gdbusobjectmanagerserver.c
index 1925805..6aefb58 100644
--- a/gio/gdbusobjectmanagerserver.c
+++ b/gio/gdbusobjectmanagerserver.c
@@ -54,7 +54,8 @@
  * manager should typically be exported at `/net/example/ExampleService1`, or
  * below (to allow for multiple object managers in a service).
  *
- * It is not supported to export an object manager at the root path, `/`.
+ * It is supported, but not recommended, to export an object manager at the root
+ * path, `/`.
  *
  * See #GDBusObjectManagerClient for the client-side code that is
  * intended to be used with #GDBusObjectManagerServer or any D-Bus
@@ -176,7 +177,10 @@ g_dbus_object_manager_server_set_property (GObject       *object,
       g_assert (manager->priv->object_path == NULL);
       g_assert (g_variant_is_object_path (g_value_get_string (value)));
       manager->priv->object_path = g_value_dup_string (value);
-      manager->priv->object_path_ending_in_slash = g_strdup_printf ("%s/", manager->priv->object_path);
+      if (g_str_equal (manager->priv->object_path, "/"))
+        manager->priv->object_path_ending_in_slash = g_strdup (manager->priv->object_path);
+      else
+        manager->priv->object_path_ending_in_slash = g_strdup_printf ("%s/", manager->priv->object_path);
       break;
 
     default:
@@ -244,8 +248,7 @@ g_dbus_object_manager_server_init (GDBusObjectManagerServer *manager)
 
 /**
  * g_dbus_object_manager_server_new:
- * @object_path: The object path to export the manager object at, which should
- * not be `/`.
+ * @object_path: The object path to export the manager object at.
  *
  * Creates a new #GDBusObjectManagerServer object.
  *
diff --git a/gio/tests/gdbus-peer-object-manager.c b/gio/tests/gdbus-peer-object-manager.c
index 01a36a5..edd44e9 100644
--- a/gio/tests/gdbus-peer-object-manager.c
+++ b/gio/tests/gdbus-peer-object-manager.c
@@ -282,7 +282,7 @@ on_result (GObject *source,
 
 static void
 test_object_manager (Test *test,
-                     gconstpointer unused)
+                     gconstpointer test_data)
 {
   GDBusObjectManager *client;
   GDBusObjectManagerServer *server;
@@ -292,18 +292,31 @@ test_object_manager (Test *test,
   GError *error = NULL;
   GDBusInterface *proxy;
   GVariant *prop;
+  const gchar *object_path = test_data;
+  gchar *number1_path = NULL, *number2_path = NULL;
 
-  server = g_dbus_object_manager_server_new ("/objects");
+  if (g_strcmp0 (object_path, "/") == 0)
+    {
+      number1_path = g_strdup ("/number_1");
+      number2_path = g_strdup ("/number_2");
+    }
+  else
+    {
+      number1_path = g_strdup_printf ("%s/number_1", object_path);
+      number2_path = g_strdup_printf ("%s/number_2", object_path);
+    }
+
+  server = g_dbus_object_manager_server_new (object_path);
 
   mock = g_object_new (mock_interface_get_type (), NULL);
   mock->number = 1;
-  skeleton = g_dbus_object_skeleton_new ("/objects/number_1");
+  skeleton = g_dbus_object_skeleton_new (number1_path);
   g_dbus_object_skeleton_add_interface (skeleton, G_DBUS_INTERFACE_SKELETON (mock));
   g_dbus_object_manager_server_export (server, skeleton);
 
   mock = g_object_new (mock_interface_get_type (), NULL);
   mock->number = 2;
-  skeleton = g_dbus_object_skeleton_new ("/objects/number_2");
+  skeleton = g_dbus_object_skeleton_new (number2_path);
   g_dbus_object_skeleton_add_interface (skeleton, G_DBUS_INTERFACE_SKELETON (mock));
   g_dbus_object_manager_server_export (server, skeleton);
 
@@ -312,19 +325,19 @@ test_object_manager (Test *test,
   dbus_name = NULL;
 
   g_dbus_object_manager_client_new (test->client, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START,
-                                    dbus_name, "/objects", NULL, NULL, NULL, NULL, on_result, test);
+                                    dbus_name, object_path, NULL, NULL, NULL, NULL, on_result, test);
 
   g_main_loop_run (test->loop);
   client = g_dbus_object_manager_client_new_finish (test->result, &error);
   g_assert_no_error (error);
   g_clear_object (&test->result);
 
-  proxy = g_dbus_object_manager_get_interface (client, "/objects/number_1", "org.mock.Interface");
+  proxy = g_dbus_object_manager_get_interface (client, number1_path, "org.mock.Interface");
   g_assert (proxy != NULL);
   prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Path");
   g_assert (prop != NULL);
   g_assert_cmpstr ((gchar *)g_variant_get_type (prop), ==, (gchar *)G_VARIANT_TYPE_OBJECT_PATH);
-  g_assert_cmpstr (g_variant_get_string (prop, NULL), ==, "/objects/number_1");
+  g_assert_cmpstr (g_variant_get_string (prop, NULL), ==, number1_path);
   g_variant_unref (prop);
   prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Number");
   g_assert (prop != NULL);
@@ -333,12 +346,12 @@ test_object_manager (Test *test,
   g_variant_unref (prop);
   g_object_unref (proxy);
 
-  proxy = g_dbus_object_manager_get_interface (client, "/objects/number_2", "org.mock.Interface");
+  proxy = g_dbus_object_manager_get_interface (client, number2_path, "org.mock.Interface");
   g_assert (proxy != NULL);
   prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Path");
   g_assert (prop != NULL);
   g_assert_cmpstr ((gchar *)g_variant_get_type (prop), ==, (gchar *)G_VARIANT_TYPE_OBJECT_PATH);
-  g_assert_cmpstr (g_variant_get_string (prop, NULL), ==, "/objects/number_2");
+  g_assert_cmpstr (g_variant_get_string (prop, NULL), ==, number2_path);
   g_variant_unref (prop);
   prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Number");
   g_assert (prop != NULL);
@@ -349,6 +362,9 @@ test_object_manager (Test *test,
 
   g_object_unref (server);
   g_object_unref (client);
+
+  g_free (number2_path);
+  g_free (number1_path);
 }
 
 int
@@ -357,7 +373,10 @@ main (int   argc,
 {
   g_test_init (&argc, &argv, NULL);
 
-  g_test_add ("/gdbus/peer-object-manager", Test, NULL, setup, test_object_manager, teardown);
+  g_test_add ("/gdbus/peer-object-manager/normal", Test, "/objects",
+              setup, test_object_manager, teardown);
+  g_test_add ("/gdbus/peer-object-manager/root", Test, "/",
+              setup, test_object_manager, teardown);
 
   return g_test_run();
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]