[glib] gdbus: Add --recurse and --only-properties options
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] gdbus: Add --recurse and --only-properties options
- Date: Thu, 9 Jun 2011 17:23:10 +0000 (UTC)
commit 30dfc353920df56e31555d9e58a690d9d552058f
Author: David Zeuthen <davidz redhat com>
Date: Thu Jun 9 13:22:18 2011 -0400
gdbus: Add --recurse and --only-properties options
These options are useful when debugging D-Bus services and working
with bug reports.
Signed-off-by: David Zeuthen <davidz redhat com>
docs/reference/gio/gdbus.xml | 47 +++++++++++-
gio/gdbus-tool.c | 185 ++++++++++++++++++++++++++++++------------
2 files changed, 178 insertions(+), 54 deletions(-)
---
diff --git a/docs/reference/gio/gdbus.xml b/docs/reference/gio/gdbus.xml
index 7729f85..4c81ce9 100644
--- a/docs/reference/gio/gdbus.xml
+++ b/docs/reference/gio/gdbus.xml
@@ -25,6 +25,12 @@
<group>
<arg choice="plain">--xml</arg>
</group>
+ <group>
+ <arg choice="plain">--recurse</arg>
+ </group>
+ <group>
+ <arg choice="plain">--only-properties</arg>
+ </group>
</cmdsynopsis>
<cmdsynopsis>
<command>gdbus</command>
@@ -94,7 +100,12 @@
<literal>org.freedesktop.DBus.Introspectable</literal> interface.
If the <option>--xml</option> option is used, the returned
introspection XML is printed, otherwise a parsed pretty
- representation is printed. </para></listitem>
+ representation is printed.
+ The <option>--recurse</option> option can be used to
+ introspect children (and their children and so on) and the
+ <option>--only-properties</option> option can be used to
+ only print the interfaces with properties.
+ </para></listitem>
</varlistentry>
<varlistentry>
<term><option>monitor</option></term>
@@ -196,6 +207,40 @@ node /org/freedesktop/NetworkManager/Devices/0 {
};
</programlisting>
<para>
+ The <option>--recurse</option> and <option>--only-properties</option> options can be useful when wanting to inspect all objects owned by a particular process:
+</para>
+<programlisting>
+$ gdbus introspect --system --dest org.freedesktop.UPower --object-path / --recurse --only-properties
+node / {
+ node /org {
+ node /org/freedesktop {
+ node /org/freedesktop/UPower {
+ interface org.freedesktop.UPower {
+ properties:
+ readonly b IsDocked = true;
+ readonly b LidForceSleep = false;
+ readonly b LidIsPresent = false;
+ readonly b LidIsClosed = false;
+ readonly b OnLowBattery = false;
+ readonly b OnBattery = false;
+ readonly b CanHibernate = true;
+ readonly b CanSuspend = true;
+ readonly s DaemonVersion = '0.9.10';
+ };
+ node /org/freedesktop/UPower/Policy {
+ };
+ node /org/freedesktop/UPower/Wakeups {
+ interface org.freedesktop.UPower.Wakeups {
+ properties:
+ readonly b HasCapability = true;
+ };
+ };
+ };
+ };
+ };
+};
+</programlisting>
+<para>
In a similar fashion, the <option>introspect</option> command can be
used to learn details about the <literal>Notify</literal> method:
</para>
diff --git a/gio/gdbus-tool.c b/gio/gdbus-tool.c
index 9fb52fc..454528b 100644
--- a/gio/gdbus-tool.c
+++ b/gio/gdbus-tool.c
@@ -1049,7 +1049,11 @@ handle_call (gint *argc,
/* ---------------------------------------------------------------------------------------------------- */
-/* TODO: dump annotations */
+static gchar *opt_introspect_dest = NULL;
+static gchar *opt_introspect_object_path = NULL;
+static gboolean opt_introspect_xml = FALSE;
+static gboolean opt_introspect_recurse = FALSE;
+static gboolean opt_introspect_only_properties = FALSE;
static void
dump_annotation (const GDBusAnnotationInfo *o,
@@ -1287,13 +1291,13 @@ dump_interface (GDBusConnection *c,
dump_annotation (o->annotations[n], indent, FALSE);
g_print ("%*sinterface %s {\n", indent, "", o->name);
- if (o->methods != NULL)
+ if (o->methods != NULL && !opt_introspect_only_properties)
{
g_print ("%*s methods:\n", indent, "");
for (n = 0; o->methods[n] != NULL; n++)
dump_method (o->methods[n], indent + 4);
}
- if (o->signals != NULL)
+ if (o->signals != NULL && !opt_introspect_only_properties)
{
g_print ("%*s signals:\n", indent, "");
for (n = 0; o->signals[n] != NULL; n++)
@@ -1315,12 +1319,18 @@ dump_interface (GDBusConnection *c,
g_hash_table_unref (properties);
}
+static gboolean
+introspect_do (GDBusConnection *c,
+ const gchar *object_path,
+ guint indent);
+
static void
dump_node (GDBusConnection *c,
const gchar *name,
const GDBusNodeInfo *o,
guint indent,
- const gchar *object_path)
+ const gchar *object_path,
+ gboolean recurse)
{
guint n;
const gchar *object_path_to_print;
@@ -1337,9 +1347,51 @@ dump_node (GDBusConnection *c,
{
g_print (" {\n");
for (n = 0; o->interfaces != NULL && o->interfaces[n] != NULL; n++)
- dump_interface (c, name, o->interfaces[n], indent + 2, object_path);
+ {
+ if (opt_introspect_only_properties)
+ {
+ if (o->interfaces[n]->properties != NULL && o->interfaces[n]->properties[0] != NULL)
+ dump_interface (c, name, o->interfaces[n], indent + 2, object_path);
+ }
+ else
+ {
+ dump_interface (c, name, o->interfaces[n], indent + 2, object_path);
+ }
+ }
for (n = 0; o->nodes != NULL && o->nodes[n] != NULL; n++)
- dump_node (NULL, NULL, o->nodes[n], indent + 2, NULL);
+ {
+ if (recurse)
+ {
+ gchar *child_path;
+ if (g_variant_is_object_path (o->nodes[n]->path))
+ {
+ child_path = g_strdup (o->nodes[n]->path);
+ /* avoid infinite loops */
+ if (g_str_has_prefix (child_path, object_path))
+ {
+ introspect_do (c, child_path, indent + 2);
+ }
+ else
+ {
+ g_print ("Skipping path %s that is not enclosed by parent %s\n",
+ child_path, object_path);
+ }
+ }
+ else
+ {
+ if (g_strcmp0 (object_path, "/") == 0)
+ child_path = g_strdup_printf ("/%s", o->nodes[n]->path);
+ else
+ child_path = g_strdup_printf ("%s/%s", object_path, o->nodes[n]->path);
+ introspect_do (c, child_path, indent + 2);
+ }
+ g_free (child_path);
+ }
+ else
+ {
+ dump_node (NULL, NULL, o->nodes[n], indent + 2, NULL, recurse);
+ }
+ }
g_print ("%*s};\n",
indent, "");
}
@@ -1349,19 +1401,79 @@ dump_node (GDBusConnection *c,
}
}
-static gchar *opt_introspect_dest = NULL;
-static gchar *opt_introspect_object_path = NULL;
-static gboolean opt_introspect_xml = FALSE;
-
static const GOptionEntry introspect_entries[] =
{
{ "dest", 'd', 0, G_OPTION_ARG_STRING, &opt_introspect_dest, N_("Destination name to introspect"), NULL},
{ "object-path", 'o', 0, G_OPTION_ARG_STRING, &opt_introspect_object_path, N_("Object path to introspect"), NULL},
{ "xml", 'x', 0, G_OPTION_ARG_NONE, &opt_introspect_xml, N_("Print XML"), NULL},
+ { "recurse", 'r', 0, G_OPTION_ARG_NONE, &opt_introspect_recurse, N_("Introspect children"), NULL},
+ { "only-properties", 'p', 0, G_OPTION_ARG_NONE, &opt_introspect_only_properties, N_("Only print properties"), NULL},
{ NULL }
};
static gboolean
+introspect_do (GDBusConnection *c,
+ const gchar *object_path,
+ guint indent)
+{
+ GError *error;
+ GVariant *result;
+ GDBusNodeInfo *node;
+ gboolean ret;
+ const gchar *xml_data;
+
+ ret = FALSE;
+ node = NULL;
+ result = NULL;
+
+ result = g_dbus_connection_call_sync (c,
+ opt_introspect_dest,
+ object_path,
+ "org.freedesktop.DBus.Introspectable",
+ "Introspect",
+ NULL,
+ G_VARIANT_TYPE ("(s)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ 3000, /* 3 sec */
+ NULL,
+ &error);
+ if (result == NULL)
+ {
+ g_printerr (_("Error: %s\n"), error->message);
+ g_error_free (error);
+ goto out;
+ }
+ g_variant_get (result, "(&s)", &xml_data);
+
+ if (opt_introspect_xml)
+ {
+ g_print ("%s", xml_data);
+ }
+ else
+ {
+ error = NULL;
+ node = g_dbus_node_info_new_for_xml (xml_data, &error);
+ if (node == NULL)
+ {
+ g_printerr (_("Error parsing introspection XML: %s\n"), error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ dump_node (c, opt_introspect_dest, node, indent, object_path, opt_introspect_recurse);
+ }
+
+ ret = TRUE;
+
+ out:
+ if (node != NULL)
+ g_dbus_node_info_unref (node);
+ if (result != NULL)
+ g_variant_unref (result);
+ return ret;
+}
+
+static gboolean
handle_introspect (gint *argc,
gchar **argv[],
gboolean request_completion,
@@ -1373,16 +1485,11 @@ handle_introspect (gint *argc,
gchar *s;
GError *error;
GDBusConnection *c;
- GVariant *result;
- const gchar *xml_data;
- GDBusNodeInfo *node;
gboolean complete_names;
gboolean complete_paths;
ret = FALSE;
c = NULL;
- node = NULL;
- result = NULL;
modify_argv0_for_command (argc, argv, "introspect");
@@ -1500,54 +1607,26 @@ handle_introspect (gint *argc,
goto out;
}
- /* All done with completion now */
- if (request_completion)
- goto out;
-
- result = g_dbus_connection_call_sync (c,
- opt_introspect_dest,
- opt_introspect_object_path,
- "org.freedesktop.DBus.Introspectable",
- "Introspect",
- NULL,
- G_VARIANT_TYPE ("(s)"),
- G_DBUS_CALL_FLAGS_NONE,
- 3000, /* 3 sec */
- NULL,
- &error);
- if (result == NULL)
+ if (request_completion && opt_introspect_object_path != NULL && !opt_introspect_recurse)
{
- g_printerr (_("Error: %s\n"), error->message);
- g_error_free (error);
- goto out;
+ g_print ("--recurse \n");
}
- g_variant_get (result, "(&s)", &xml_data);
- if (opt_introspect_xml)
+ if (request_completion && opt_introspect_object_path != NULL && !opt_introspect_only_properties)
{
- g_print ("%s", xml_data);
+ g_print ("--only-properties \n");
}
- else
- {
- error = NULL;
- node = g_dbus_node_info_new_for_xml (xml_data, &error);
- if (node == NULL)
- {
- g_printerr (_("Error parsing introspection XML: %s\n"), error->message);
- g_error_free (error);
- goto out;
- }
- dump_node (c, opt_introspect_dest, node, 0, opt_introspect_object_path);
- }
+ /* All done with completion now */
+ if (request_completion)
+ goto out;
+
+ if (!introspect_do (c, opt_introspect_object_path, 0))
+ goto out;
ret = TRUE;
out:
- if (node != NULL)
- g_dbus_node_info_unref (node);
- if (result != NULL)
- g_variant_unref (result);
if (c != NULL)
g_object_unref (c);
g_option_context_free (o);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]