diff options
| author | Havoc Pennington <hp@redhat.com> | 2005-01-30 05:18:44 +0000 | 
|---|---|---|
| committer | Havoc Pennington <hp@redhat.com> | 2005-01-30 05:18:44 +0000 | 
| commit | 41f52c96d651003b3d0a266a582d401228a8368e (patch) | |
| tree | 3b217cef0c0b9db03aa580cb541b7d686732055a | |
| parent | 2922b0e88ba00b0067c23633075629108ad8a496 (diff) | |
2005-01-30  Havoc Pennington  <hp@redhat.com>
        dbus-viewer introspected and displayed the bus driver
	* dbus/dbus-object-tree.c
	(object_tree_test_iteration): add tests for a handler registered on "/"
	* dbus/dbus-object-tree.c
	(_dbus_decompose_path): fix to handle path "/" properly
	(run_decompose_tests): add tests for path decomposition
	* glib/dbus-gutils.c (_dbus_gutils_split_path): fix to handle "/"
	properly
	* glib/dbus-gobject.c (handle_introspect): fix quotes
	* test/glib/run-test.sh: support launching the bus, then running
	dbus-viewer
	* test/glib/test-service-glib.c (main): put in a trivial gobject
	subclass and register it on the connection
	* bus/driver.c (bus_driver_handle_introspect): implement
	introspection of the bus driver service
	* dbus/dbus-protocol.h: add #defines for the XML namespace,
	identifiers, doctype decl
	* bus/driver.c (bus_driver_handle_get_service_owner): handle
	attempts to get owner of DBUS_SERVICE_ORG_FREEDESKTOP_DBUS by
	returning the service unchanged.
	(bus_driver_handle_message): remove old check for reply_serial in
	method calls, now the message type deals with that
	(bus_driver_handle_message): handle NULL interface
	* glib/dbus-gproxy.c (dbus_g_proxy_get_bus_name): new function
	* glib/dbus-gloader-expat.c (description_load_from_string): allow
	-1 for len
	* tools/dbus-viewer.c: add support for introspecting a service on
	a bus
	* glib/dbus-gproxy.c (dbus_g_pending_call_ref): add
	(dbus_g_pending_call_unref): add
| -rw-r--r-- | ChangeLog | 48 | ||||
| -rw-r--r-- | bus/driver.c | 134 | ||||
| -rw-r--r-- | dbus/dbus-glib.h | 3 | ||||
| -rw-r--r-- | dbus/dbus-marshal-validate.c | 2 | ||||
| -rw-r--r-- | dbus/dbus-object-tree.c | 266 | ||||
| -rw-r--r-- | dbus/dbus-protocol.h | 6 | ||||
| -rw-r--r-- | glib/dbus-gidl.c | 14 | ||||
| -rw-r--r-- | glib/dbus-gidl.h | 3 | ||||
| -rw-r--r-- | glib/dbus-gloader-expat.c | 4 | ||||
| -rw-r--r-- | glib/dbus-gobject.c | 16 | ||||
| -rw-r--r-- | glib/dbus-gproxy.c | 62 | ||||
| -rw-r--r-- | glib/dbus-gutils.c | 20 | ||||
| -rwxr-xr-x | test/glib/run-test.sh | 9 | ||||
| -rw-r--r-- | test/glib/test-service-glib.c | 46 | ||||
| -rw-r--r-- | tools/dbus-viewer.c | 145 | 
15 files changed, 666 insertions, 112 deletions
@@ -1,3 +1,49 @@ +2005-01-30  Havoc Pennington  <hp@redhat.com> + +        dbus-viewer introspected and displayed the bus driver +	 +	* dbus/dbus-object-tree.c  +	(object_tree_test_iteration): add tests for a handler registered on "/" + +	* dbus/dbus-object-tree.c +	(_dbus_decompose_path): fix to handle path "/" properly +	(run_decompose_tests): add tests for path decomposition +	 +	* glib/dbus-gutils.c (_dbus_gutils_split_path): fix to handle "/" +	properly + +	* glib/dbus-gobject.c (handle_introspect): fix quotes + +	* test/glib/run-test.sh: support launching the bus, then running +	dbus-viewer + +	* test/glib/test-service-glib.c (main): put in a trivial gobject +	subclass and register it on the connection + +	* bus/driver.c (bus_driver_handle_introspect): implement +	introspection of the bus driver service + +	* dbus/dbus-protocol.h: add #defines for the XML namespace, +	identifiers, doctype decl + +	* bus/driver.c (bus_driver_handle_get_service_owner): handle +	attempts to get owner of DBUS_SERVICE_ORG_FREEDESKTOP_DBUS by  +	returning the service unchanged. +	(bus_driver_handle_message): remove old check for reply_serial in +	method calls, now the message type deals with that +	(bus_driver_handle_message): handle NULL interface + +	* glib/dbus-gproxy.c (dbus_g_proxy_get_bus_name): new function + +	* glib/dbus-gloader-expat.c (description_load_from_string): allow +	-1 for len + +	* tools/dbus-viewer.c: add support for introspecting a service on +	a bus + +	* glib/dbus-gproxy.c (dbus_g_pending_call_ref): add +	(dbus_g_pending_call_unref): add +  2005-01-29  Havoc Pennington  <hp@redhat.com>  	* tools/dbus-tree-view.c: add support for displaying properties. @@ -6,7 +52,7 @@  	* glib/dbus-gobject.c (handle_introspect): return  	org.freedesktop.Properties and org.freedesktop.Introspectable -	interfaces when we are introspected.	 +	interfaces when we are introspected.  	* doc/dbus-specification.xml: allow empty interface name when   	Get/Set a property diff --git a/bus/driver.c b/bus/driver.c index 3a9e555d..58b8fcbf 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -792,24 +792,34 @@ bus_driver_handle_get_service_owner (DBusConnection *connection,    _dbus_string_init_const (&str, text);    service = bus_registry_lookup (registry, &str); -  if (service == NULL) +  if (service == NULL && +      _dbus_string_equal_c_str (&str, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS)) +    { +      /* ORG_FREEDESKTOP_DBUS owns itself */ +      base_name = DBUS_SERVICE_ORG_FREEDESKTOP_DBUS; +    } +  else if (service == NULL)      {        dbus_set_error (error,  -		      DBUS_ERROR_NAME_HAS_NO_OWNER, -		      "Could not get owner of name '%s': no such name", text); +                      DBUS_ERROR_NAME_HAS_NO_OWNER, +                      "Could not get owner of name '%s': no such name", text);        goto failed;      } - -  base_name = bus_connection_get_name (bus_service_get_primary_owner (service)); -  if (base_name == NULL) +  else      { -      /* FIXME - how is this error possible? */ -      dbus_set_error (error, -		      DBUS_ERROR_FAILED, -		      "Could not determine unique name for '%s'", text); -      goto failed; +      base_name = bus_connection_get_name (bus_service_get_primary_owner (service)); +      if (base_name == NULL) +        { +          /* FIXME - how is this error possible? */ +          dbus_set_error (error, +                          DBUS_ERROR_FAILED, +                          "Could not determine unique name for '%s'", text); +          goto failed; +        } +      _dbus_assert (*base_name == ':');            } -  _dbus_assert (*base_name == ':'); + +  _dbus_assert (base_name != NULL);    reply = dbus_message_new_method_return (message);    if (reply == NULL) @@ -1040,13 +1050,89 @@ struct    { "ReloadConfig", bus_driver_handle_reload_config }  }; +static dbus_bool_t +bus_driver_handle_introspect (DBusConnection *connection, +                              BusTransaction *transaction, +                              DBusMessage    *message, +                              DBusError      *error) +{ +  DBusString xml; +  DBusMessage *reply; +  const char *v_STRING; + +  _dbus_verbose ("Introspect() on bus driver\n"); +   +  _DBUS_ASSERT_ERROR_IS_CLEAR (error); + +  reply = NULL; + +  if (! dbus_message_get_args (message, error, +			       DBUS_TYPE_INVALID)) +    { +      _DBUS_ASSERT_ERROR_IS_SET (error); +      return FALSE; +    } + +  if (!_dbus_string_init (&xml)) +    { +      BUS_SET_OOM (error); +      return FALSE; +    } + +  if (!_dbus_string_append (&xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE)) +    goto oom; +  if (!_dbus_string_append (&xml, "<node>\n")) +    goto oom; +  if (!_dbus_string_append (&xml, "  <interface name=\"org.freedesktop.Introspectable\">\n")) +    goto oom; +  if (!_dbus_string_append (&xml, "    <method name=\"Introspect\">\n")) +    goto oom; +  if (!_dbus_string_append (&xml, "      <arg name=\"data\" direction=\"out\" type=\"string\"/>\n")) +    goto oom; +  if (!_dbus_string_append (&xml, "    </method>\n")) +    goto oom; +  if (!_dbus_string_append (&xml, "  </interface>\n")) +    goto oom; +   +  if (!_dbus_string_append (&xml, "</node>\n")) +    goto oom; + +  reply = dbus_message_new_method_return (message); +  if (reply == NULL) +    goto oom; + +  v_STRING = _dbus_string_get_const_data (&xml); +  if (! dbus_message_append_args (reply, +                                  DBUS_TYPE_STRING, &v_STRING, +                                  DBUS_TYPE_INVALID)) +    goto oom; + +  if (! bus_transaction_send_from_driver (transaction, connection, reply)) +    goto oom; + +  dbus_message_unref (reply); +  _dbus_string_free (&xml); + +  return TRUE; + + oom: +  BUS_SET_OOM (error); + +  if (reply) +    dbus_message_unref (reply); + +  _dbus_string_free (&xml); +   +  return FALSE; +} +  dbus_bool_t  bus_driver_handle_message (DBusConnection *connection,                             BusTransaction *transaction,  			   DBusMessage    *message,                             DBusError      *error)  { -  const char *name, *sender; +  const char *name, *sender, *interface;    int i;    _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -1057,17 +1143,25 @@ bus_driver_handle_message (DBusConnection *connection,        return TRUE; /* we just ignore this */      } -  _dbus_assert (dbus_message_get_interface (message) != NULL); +  if (dbus_message_is_method_call (message, +                                   DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE, +                                   "Introspect")) +    return bus_driver_handle_introspect (connection, transaction, message, error); +   +  interface = dbus_message_get_interface (message); +  if (interface == NULL) +    interface = DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS; +      _dbus_assert (dbus_message_get_member (message) != NULL); - +      name = dbus_message_get_member (message);    sender = dbus_message_get_sender (message); -  if (strcmp (dbus_message_get_interface (message), +  if (strcmp (interface,                DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS) != 0)      {        _dbus_verbose ("Driver got message to unknown interface \"%s\"\n", -                     dbus_message_get_interface (message)); +                     interface);        goto unknown;      } @@ -1076,12 +1170,6 @@ bus_driver_handle_message (DBusConnection *connection,    /* security checks should have kept this from getting here */    _dbus_assert (sender != NULL || strcmp (name, "Hello") == 0); - -  if (dbus_message_get_reply_serial (message) != 0) -    { -      _dbus_verbose ("Client sent a reply to the bus driver, ignoring it\n"); -      return TRUE; -    }    i = 0;    while (i < _DBUS_N_ELEMENTS (message_handlers)) diff --git a/dbus/dbus-glib.h b/dbus/dbus-glib.h index de53d14a..3e73b98f 100644 --- a/dbus/dbus-glib.h +++ b/dbus/dbus-glib.h @@ -145,7 +145,10 @@ void              dbus_g_proxy_call_no_reply         (DBusGProxy        *proxy,                                                        const char        *method,                                                        int                first_arg_type,                                                        ...); +const char*       dbus_g_proxy_get_bus_name          (DBusGProxy        *proxy); +DBusGPendingCall* dbus_g_pending_call_ref            (DBusGPendingCall  *call); +void              dbus_g_pending_call_unref          (DBusGPendingCall  *call);  #undef DBUS_INSIDE_DBUS_GLIB_H diff --git a/dbus/dbus-marshal-validate.c b/dbus/dbus-marshal-validate.c index e57be5c7..d9b85cb7 100644 --- a/dbus/dbus-marshal-validate.c +++ b/dbus/dbus-marshal-validate.c @@ -573,7 +573,7 @@ _dbus_validate_path (const DBusString  *str,    _dbus_assert (start >= 0);    _dbus_assert (len >= 0);    _dbus_assert (start <= _dbus_string_get_length (str)); - +      if (len > _dbus_string_get_length (str) - start)      return FALSE; diff --git a/dbus/dbus-object-tree.c b/dbus/dbus-object-tree.c index 694185fb..f8797595 100644 --- a/dbus/dbus-object-tree.c +++ b/dbus/dbus-object-tree.c @@ -630,6 +630,9 @@ handle_default_introspect_unlocked (DBusObjectTree          *tree,    if (!_dbus_object_tree_list_registered_unlocked (tree, path, &children))      goto out; +  if (!_dbus_string_append (&xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE)) +    goto out; +      if (!_dbus_string_append (&xml, "<node>\n"))      goto out; @@ -945,6 +948,7 @@ _dbus_object_tree_list_registered_and_unlock (DBusObjectTree *tree,  /**   * Decompose an object path.  A path of just "/" is   * represented as an empty vector of strings. + * The path need not be nul terminated.   *    * @param data the path data   * @param len  the length of the path string @@ -962,19 +966,22 @@ _dbus_decompose_path (const char*     data,    int i, j, comp;    _dbus_assert (data != NULL); - +    #if VERBOSE_DECOMPOSE    _dbus_verbose ("Decomposing path \"%s\"\n",                   data);  #endif    n_components = 0; -  i = 0; -  while (i < len) +  if (len > 1) /* if path is not just "/" */      { -      if (data[i] == '/') -        n_components += 1; -      ++i; +      i = 0; +      while (i < len) +        { +          if (data[i] == '/') +            n_components += 1; +          ++i; +        }      }    retval = dbus_new0 (char*, n_components + 1); @@ -983,9 +990,14 @@ _dbus_decompose_path (const char*     data,      return FALSE;    comp = 0; -  i = 0; -  while (i < len) +  if (n_components == 0) +    i = 1; +  else +    i = 0; +  while (comp < n_components)      { +      _dbus_assert (i < len); +              if (data[i] == '/')          ++i;        j = i; @@ -1037,22 +1049,31 @@ static char*  flatten_path (const char **path)  {    DBusString str; -  int i;    char *s;    if (!_dbus_string_init (&str))      return NULL; -  i = 0; -  while (path[i]) +  if (path[0] == NULL)      {        if (!_dbus_string_append_byte (&str, '/'))          goto nomem; - -      if (!_dbus_string_append (&str, path[i])) -        goto nomem; - -      ++i; +    } +  else +    { +      int i; +       +      i = 0; +      while (path[i]) +        { +          if (!_dbus_string_append_byte (&str, '/')) +            goto nomem; +           +          if (!_dbus_string_append (&str, path[i])) +            goto nomem; +           +          ++i; +        }      }    if (!_dbus_string_steal_data (&str, &s)) @@ -1191,7 +1212,7 @@ do_register (DBusObjectTree *tree,  {    DBusObjectPathVTable vtable = { test_unregister_function,                                    test_message_function, NULL }; - +      tree_test_data[i].message_handled = FALSE;    tree_test_data[i].handler_unregistered = FALSE;    tree_test_data[i].handler_fallback = fallback; @@ -1278,17 +1299,82 @@ do_test_dispatch (DBusObjectTree *tree,  }  static size_t -string_array_length (char **array) +string_array_length (const char **array)  {    size_t i;    for (i = 0; array[i]; i++) ;    return i;  } +typedef struct +{ +  const char *path; +  const char *result[20]; +} DecomposePathTest; + +static DecomposePathTest decompose_tests[] = { +  { "/foo", { "foo", NULL } }, +  { "/foo/bar", { "foo", "bar", NULL } }, +  { "/", { NULL } }, +  { "/a/b", { "a", "b", NULL } }, +  { "/a/b/c", { "a", "b", "c", NULL } }, +  { "/a/b/c/d", { "a", "b", "c", "d", NULL } }, +  { "/foo/bar/q", { "foo", "bar", "q", NULL } }, +  { "/foo/bar/this/is/longer", { "foo", "bar", "this", "is", "longer", NULL } } +}; + +static dbus_bool_t +run_decompose_tests (void) +{ +  int i; + +  i = 0; +  while (i < _DBUS_N_ELEMENTS (decompose_tests)) +    { +      char **result; +      int    result_len; +      int    expected_len; + +      if (!_dbus_decompose_path (decompose_tests[i].path, +                                 strlen (decompose_tests[i].path), +                                 &result, &result_len)) +        return FALSE; + +      expected_len = string_array_length (decompose_tests[i].result); +       +      if (result_len != (int) string_array_length ((const char**)result) || +          expected_len != result_len || +          path_contains (decompose_tests[i].result, +                         (const char**) result) != STR_EQUAL) +        { +          int real_len = string_array_length ((const char**)result); +          _dbus_warn ("Expected decompose of %s to have len %d, returned %d, appears to have %d\n", +                      decompose_tests[i].path, expected_len, result_len, +                      real_len); +          _dbus_warn ("Decompose resulted in elements: { "); +          i = 0; +          while (i < real_len) +            { +              _dbus_warn ("\"%s\"%s", result[i], +                          (i + 1) == real_len ? "" : ", "); +              ++i; +            } +          _dbus_warn ("}\n"); +          _dbus_assert_not_reached ("path decompose failed\n"); +        } + +      dbus_free_string_array (result); + +      ++i; +    } +   +  return TRUE; +}  static dbus_bool_t  object_tree_test_iteration (void *data)  { +  const char *path0[] = { NULL };    const char *path1[] = { "foo", NULL };    const char *path2[] = { "foo", "bar", NULL };    const char *path3[] = { "foo", "bar", "baz", NULL }; @@ -1298,19 +1384,46 @@ object_tree_test_iteration (void *data)    const char *path7[] = { "blah", "boof", "this", "is", "really", "long", NULL };    const char *path8[] = { "childless", NULL };    DBusObjectTree *tree; -  TreeTestData tree_test_data[8]; +  TreeTestData tree_test_data[9];    int i;    dbus_bool_t exact_match; +  if (!run_decompose_tests ()) +    return FALSE; +      tree = NULL;    tree = _dbus_object_tree_new (NULL);    if (tree == NULL)      goto out; -  if (!do_register (tree, path1, TRUE, 0, tree_test_data)) +  if (!do_register (tree, path0, TRUE, 0, tree_test_data)) +    goto out; + +  _dbus_assert (find_subtree (tree, path0, NULL)); +  _dbus_assert (!find_subtree (tree, path1, NULL)); +  _dbus_assert (!find_subtree (tree, path2, NULL)); +  _dbus_assert (!find_subtree (tree, path3, NULL)); +  _dbus_assert (!find_subtree (tree, path4, NULL)); +  _dbus_assert (!find_subtree (tree, path5, NULL)); +  _dbus_assert (!find_subtree (tree, path6, NULL)); +  _dbus_assert (!find_subtree (tree, path7, NULL)); +  _dbus_assert (!find_subtree (tree, path8, NULL)); + +  _dbus_assert (find_handler (tree, path0, &exact_match) && exact_match); +  _dbus_assert (find_handler (tree, path1, &exact_match) == tree->root && !exact_match); +  _dbus_assert (find_handler (tree, path2, &exact_match) == tree->root && !exact_match); +  _dbus_assert (find_handler (tree, path3, &exact_match) == tree->root && !exact_match); +  _dbus_assert (find_handler (tree, path4, &exact_match) == tree->root && !exact_match); +  _dbus_assert (find_handler (tree, path5, &exact_match) == tree->root && !exact_match); +  _dbus_assert (find_handler (tree, path6, &exact_match) == tree->root && !exact_match); +  _dbus_assert (find_handler (tree, path7, &exact_match) == tree->root && !exact_match); +  _dbus_assert (find_handler (tree, path8, &exact_match) == tree->root && !exact_match); +   +  if (!do_register (tree, path1, TRUE, 1, tree_test_data))      goto out; +  _dbus_assert (find_subtree (tree, path0, NULL));    _dbus_assert (find_subtree (tree, path1, NULL));    _dbus_assert (!find_subtree (tree, path2, NULL));    _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1320,6 +1433,7 @@ object_tree_test_iteration (void *data)    _dbus_assert (!find_subtree (tree, path7, NULL));    _dbus_assert (!find_subtree (tree, path8, NULL)); +  _dbus_assert (find_handler (tree, path0, &exact_match) &&  exact_match);    _dbus_assert (find_handler (tree, path1, &exact_match) &&  exact_match);    _dbus_assert (find_handler (tree, path2, &exact_match) && !exact_match);    _dbus_assert (find_handler (tree, path3, &exact_match) && !exact_match); @@ -1329,7 +1443,7 @@ object_tree_test_iteration (void *data)    _dbus_assert (find_handler (tree, path7, &exact_match) == tree->root && !exact_match);    _dbus_assert (find_handler (tree, path8, &exact_match) == tree->root && !exact_match); -  if (!do_register (tree, path2, TRUE, 1, tree_test_data)) +  if (!do_register (tree, path2, TRUE, 2, tree_test_data))      goto out;    _dbus_assert (find_subtree (tree, path1, NULL)); @@ -1341,9 +1455,10 @@ object_tree_test_iteration (void *data)    _dbus_assert (!find_subtree (tree, path7, NULL));    _dbus_assert (!find_subtree (tree, path8, NULL)); -  if (!do_register (tree, path3, TRUE, 2, tree_test_data)) +  if (!do_register (tree, path3, TRUE, 3, tree_test_data))      goto out; +  _dbus_assert (find_subtree (tree, path0, NULL));    _dbus_assert (find_subtree (tree, path1, NULL));    _dbus_assert (find_subtree (tree, path2, NULL));    _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1353,9 +1468,10 @@ object_tree_test_iteration (void *data)    _dbus_assert (!find_subtree (tree, path7, NULL));    _dbus_assert (!find_subtree (tree, path8, NULL)); -  if (!do_register (tree, path4, TRUE, 3, tree_test_data)) +  if (!do_register (tree, path4, TRUE, 4, tree_test_data))      goto out; +  _dbus_assert (find_subtree (tree, path0, NULL));    _dbus_assert (find_subtree (tree, path1, NULL));    _dbus_assert (find_subtree (tree, path2, NULL));    _dbus_assert (find_subtree (tree, path3, NULL));   @@ -1365,9 +1481,10 @@ object_tree_test_iteration (void *data)    _dbus_assert (!find_subtree (tree, path7, NULL));    _dbus_assert (!find_subtree (tree, path8, NULL)); -  if (!do_register (tree, path5, TRUE, 4, tree_test_data)) +  if (!do_register (tree, path5, TRUE, 5, tree_test_data))      goto out; +  _dbus_assert (find_subtree (tree, path0, NULL));    _dbus_assert (find_subtree (tree, path1, NULL));    _dbus_assert (find_subtree (tree, path2, NULL));    _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1376,7 +1493,8 @@ object_tree_test_iteration (void *data)    _dbus_assert (!find_subtree (tree, path6, NULL));    _dbus_assert (!find_subtree (tree, path7, NULL));    _dbus_assert (!find_subtree (tree, path8, NULL)); -   + +  _dbus_assert (find_handler (tree, path0, &exact_match) == tree->root &&  exact_match);    _dbus_assert (find_handler (tree, path1, &exact_match) != tree->root &&  exact_match);    _dbus_assert (find_handler (tree, path2, &exact_match) != tree->root &&  exact_match);    _dbus_assert (find_handler (tree, path3, &exact_match) != tree->root &&  exact_match); @@ -1386,9 +1504,10 @@ object_tree_test_iteration (void *data)    _dbus_assert (find_handler (tree, path7, &exact_match) != tree->root && !exact_match);    _dbus_assert (find_handler (tree, path8, &exact_match) == tree->root && !exact_match); -  if (!do_register (tree, path6, TRUE, 5, tree_test_data)) +  if (!do_register (tree, path6, TRUE, 6, tree_test_data))      goto out; +  _dbus_assert (find_subtree (tree, path0, NULL));    _dbus_assert (find_subtree (tree, path1, NULL));    _dbus_assert (find_subtree (tree, path2, NULL));    _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1398,9 +1517,10 @@ object_tree_test_iteration (void *data)    _dbus_assert (!find_subtree (tree, path7, NULL));    _dbus_assert (!find_subtree (tree, path8, NULL)); -  if (!do_register (tree, path7, TRUE, 6, tree_test_data)) +  if (!do_register (tree, path7, TRUE, 7, tree_test_data))      goto out; +  _dbus_assert (find_subtree (tree, path0, NULL));    _dbus_assert (find_subtree (tree, path1, NULL));    _dbus_assert (find_subtree (tree, path2, NULL));    _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1410,9 +1530,10 @@ object_tree_test_iteration (void *data)    _dbus_assert (find_subtree (tree, path7, NULL));    _dbus_assert (!find_subtree (tree, path8, NULL)); -  if (!do_register (tree, path8, TRUE, 7, tree_test_data)) +  if (!do_register (tree, path8, TRUE, 8, tree_test_data))      goto out; +  _dbus_assert (find_subtree (tree, path0, NULL));    _dbus_assert (find_subtree (tree, path1, NULL));    _dbus_assert (find_subtree (tree, path2, NULL));    _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1421,7 +1542,8 @@ object_tree_test_iteration (void *data)    _dbus_assert (find_subtree (tree, path6, NULL));    _dbus_assert (find_subtree (tree, path7, NULL));    _dbus_assert (find_subtree (tree, path8, NULL)); -   + +  _dbus_assert (find_handler (tree, path0, &exact_match) == tree->root &&  exact_match);    _dbus_assert (find_handler (tree, path1, &exact_match) != tree->root && exact_match);    _dbus_assert (find_handler (tree, path2, &exact_match) != tree->root && exact_match);    _dbus_assert (find_handler (tree, path3, &exact_match) != tree->root && exact_match); @@ -1441,7 +1563,7 @@ object_tree_test_iteration (void *data)      _dbus_object_tree_list_registered_unlocked (tree, path1, &child_entries);      if (child_entries != NULL)        { -	nb = string_array_length (child_entries); +	nb = string_array_length ((const char**)child_entries);  	_dbus_assert (nb == 1);  	dbus_free_string_array (child_entries);        } @@ -1449,7 +1571,7 @@ object_tree_test_iteration (void *data)      _dbus_object_tree_list_registered_unlocked (tree, path2, &child_entries);      if (child_entries != NULL)        { -	nb = string_array_length (child_entries); +	nb = string_array_length ((const char**)child_entries);  	_dbus_assert (nb == 2);  	dbus_free_string_array (child_entries);        } @@ -1457,7 +1579,7 @@ object_tree_test_iteration (void *data)      _dbus_object_tree_list_registered_unlocked (tree, path8, &child_entries);      if (child_entries != NULL)        { -	nb = string_array_length (child_entries); +	nb = string_array_length ((const char**)child_entries);  	_dbus_assert (nb == 0);  	dbus_free_string_array (child_entries);        } @@ -1465,7 +1587,7 @@ object_tree_test_iteration (void *data)      _dbus_object_tree_list_registered_unlocked (tree, root, &child_entries);      if (child_entries != NULL)        { -	nb = string_array_length (child_entries); +	nb = string_array_length ((const char**)child_entries);  	_dbus_assert (nb == 3);  	dbus_free_string_array (child_entries);        } @@ -1487,25 +1609,40 @@ object_tree_test_iteration (void *data)    if (tree == NULL)      goto out; -  if (!do_register (tree, path1, TRUE, 0, tree_test_data)) +  if (!do_register (tree, path0, TRUE, 0, tree_test_data)) +    goto out; +  if (!do_register (tree, path1, TRUE, 1, tree_test_data))      goto out; -  if (!do_register (tree, path2, TRUE, 1, tree_test_data)) +  if (!do_register (tree, path2, TRUE, 2, tree_test_data))      goto out; -  if (!do_register (tree, path3, TRUE, 2, tree_test_data)) +  if (!do_register (tree, path3, TRUE, 3, tree_test_data))      goto out; -  if (!do_register (tree, path4, TRUE, 3, tree_test_data)) +  if (!do_register (tree, path4, TRUE, 4, tree_test_data))      goto out; -  if (!do_register (tree, path5, TRUE, 4, tree_test_data)) +  if (!do_register (tree, path5, TRUE, 5, tree_test_data))      goto out; -  if (!do_register (tree, path6, TRUE, 5, tree_test_data)) +  if (!do_register (tree, path6, TRUE, 6, tree_test_data))      goto out; -  if (!do_register (tree, path7, TRUE, 6, tree_test_data)) +  if (!do_register (tree, path7, TRUE, 7, tree_test_data))      goto out; -  if (!do_register (tree, path8, TRUE, 7, tree_test_data)) +  if (!do_register (tree, path8, TRUE, 8, tree_test_data))      goto out; + +  _dbus_object_tree_unregister_and_unlock (tree, path0); + +  _dbus_assert (!find_subtree (tree, path0, NULL)); +  _dbus_assert (find_subtree (tree, path1, NULL)); +  _dbus_assert (find_subtree (tree, path2, NULL)); +  _dbus_assert (find_subtree (tree, path3, NULL)); +  _dbus_assert (find_subtree (tree, path4, NULL)); +  _dbus_assert (find_subtree (tree, path5, NULL)); +  _dbus_assert (find_subtree (tree, path6, NULL)); +  _dbus_assert (find_subtree (tree, path7, NULL)); +  _dbus_assert (find_subtree (tree, path8, NULL));    _dbus_object_tree_unregister_and_unlock (tree, path1); +  _dbus_assert (!find_subtree (tree, path0, NULL));    _dbus_assert (!find_subtree (tree, path1, NULL));    _dbus_assert (find_subtree (tree, path2, NULL));    _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1517,6 +1654,7 @@ object_tree_test_iteration (void *data)    _dbus_object_tree_unregister_and_unlock (tree, path2); +  _dbus_assert (!find_subtree (tree, path0, NULL));    _dbus_assert (!find_subtree (tree, path1, NULL));    _dbus_assert (!find_subtree (tree, path2, NULL));    _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1528,6 +1666,7 @@ object_tree_test_iteration (void *data)    _dbus_object_tree_unregister_and_unlock (tree, path3); +  _dbus_assert (!find_subtree (tree, path0, NULL));    _dbus_assert (!find_subtree (tree, path1, NULL));    _dbus_assert (!find_subtree (tree, path2, NULL));    _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1539,6 +1678,7 @@ object_tree_test_iteration (void *data)    _dbus_object_tree_unregister_and_unlock (tree, path4); +  _dbus_assert (!find_subtree (tree, path0, NULL));    _dbus_assert (!find_subtree (tree, path1, NULL));    _dbus_assert (!find_subtree (tree, path2, NULL));    _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1550,6 +1690,7 @@ object_tree_test_iteration (void *data)    _dbus_object_tree_unregister_and_unlock (tree, path5); +  _dbus_assert (!find_subtree (tree, path0, NULL));    _dbus_assert (!find_subtree (tree, path1, NULL));    _dbus_assert (!find_subtree (tree, path2, NULL));    _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1561,6 +1702,7 @@ object_tree_test_iteration (void *data)    _dbus_object_tree_unregister_and_unlock (tree, path6); +  _dbus_assert (!find_subtree (tree, path0, NULL));    _dbus_assert (!find_subtree (tree, path1, NULL));    _dbus_assert (!find_subtree (tree, path2, NULL));    _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1572,6 +1714,7 @@ object_tree_test_iteration (void *data)    _dbus_object_tree_unregister_and_unlock (tree, path7); +  _dbus_assert (!find_subtree (tree, path0, NULL));    _dbus_assert (!find_subtree (tree, path1, NULL));    _dbus_assert (!find_subtree (tree, path2, NULL));    _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1583,6 +1726,7 @@ object_tree_test_iteration (void *data)    _dbus_object_tree_unregister_and_unlock (tree, path8); +  _dbus_assert (!find_subtree (tree, path0, NULL));    _dbus_assert (!find_subtree (tree, path1, NULL));    _dbus_assert (!find_subtree (tree, path2, NULL));    _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1601,43 +1745,47 @@ object_tree_test_iteration (void *data)      }    /* Register it all again, and test dispatch */ - -  if (!do_register (tree, path1, FALSE, 0, tree_test_data)) +   +  if (!do_register (tree, path0, TRUE, 0, tree_test_data)) +    goto out; +  if (!do_register (tree, path1, FALSE, 1, tree_test_data))      goto out; -  if (!do_register (tree, path2, TRUE, 1, tree_test_data)) +  if (!do_register (tree, path2, TRUE, 2, tree_test_data))      goto out; -  if (!do_register (tree, path3, TRUE, 2, tree_test_data)) +  if (!do_register (tree, path3, TRUE, 3, tree_test_data))      goto out; -  if (!do_register (tree, path4, TRUE, 3, tree_test_data)) +  if (!do_register (tree, path4, TRUE, 4, tree_test_data))      goto out; -  if (!do_register (tree, path5, TRUE, 4, tree_test_data)) +  if (!do_register (tree, path5, TRUE, 5, tree_test_data))      goto out; -  if (!do_register (tree, path6, FALSE, 5, tree_test_data)) +  if (!do_register (tree, path6, FALSE, 6, tree_test_data))      goto out; -  if (!do_register (tree, path7, TRUE, 6, tree_test_data)) +  if (!do_register (tree, path7, TRUE, 7, tree_test_data))      goto out; -  if (!do_register (tree, path8, TRUE, 7, tree_test_data)) +  if (!do_register (tree, path8, TRUE, 8, tree_test_data))      goto out;  #if 0    spew_tree (tree);  #endif -   -  if (!do_test_dispatch (tree, path1, 0, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + +  if (!do_test_dispatch (tree, path0, 0, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) +    goto out; +  if (!do_test_dispatch (tree, path1, 1, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))      goto out; -  if (!do_test_dispatch (tree, path2, 1, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) +  if (!do_test_dispatch (tree, path2, 2, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))      goto out; -  if (!do_test_dispatch (tree, path3, 2, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) +  if (!do_test_dispatch (tree, path3, 3, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))      goto out; -  if (!do_test_dispatch (tree, path4, 3, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) +  if (!do_test_dispatch (tree, path4, 4, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))      goto out; -  if (!do_test_dispatch (tree, path5, 4, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) +  if (!do_test_dispatch (tree, path5, 5, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))      goto out; -  if (!do_test_dispatch (tree, path6, 5, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) +  if (!do_test_dispatch (tree, path6, 6, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))      goto out; -  if (!do_test_dispatch (tree, path7, 6, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) +  if (!do_test_dispatch (tree, path7, 7, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))      goto out; -  if (!do_test_dispatch (tree, path8, 7, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) +  if (!do_test_dispatch (tree, path8, 8, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))      goto out;   out: diff --git a/dbus/dbus-protocol.h b/dbus/dbus-protocol.h index f72efb60..c662d721 100644 --- a/dbus/dbus-protocol.h +++ b/dbus/dbus-protocol.h @@ -272,6 +272,12 @@ extern "C" {  #define DBUS_ERROR_SPAWN_FAILED               "org.freedesktop.DBus.Error.Spawn.Failed"  #define DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN    "org.freedesktop.DBus.Error.UnixProcessIdUnknown" +#define DBUS_INTROSPECT_1_0_XML_NAMESPACE         "http://www.freedesktop.org/standards/dbus" +#define DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +#define DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd" +#define DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<!DOCTYPE node PUBLIC \""DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER"\"\n\""DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER"\">\n" + +  #ifdef __cplusplus  }  #endif diff --git a/glib/dbus-gidl.c b/glib/dbus-gidl.c index cabc406b..8e0dc0da 100644 --- a/glib/dbus-gidl.c +++ b/glib/dbus-gidl.c @@ -303,6 +303,20 @@ node_info_add_node (NodeInfo *info,    info->nodes = g_slist_append (info->nodes, node);  } +void +node_info_replace_node (NodeInfo            *info, +                        NodeInfo            *old_child, +                        NodeInfo            *new_child) +{ +  GSList *link; + +  node_info_ref (new_child); /* before unref old_child in case they are the same */ +  link = g_slist_find (info->nodes, old_child); +  g_assert (link != NULL); +  node_info_unref (old_child); +  link->data = new_child; +} +  InterfaceInfo*  interface_info_new (const char *name)  { diff --git a/glib/dbus-gidl.h b/glib/dbus-gidl.h index fffbddfc..88d5c6e7 100644 --- a/glib/dbus-gidl.h +++ b/glib/dbus-gidl.h @@ -83,6 +83,9 @@ void                node_info_add_interface       (NodeInfo            *info,                                                     InterfaceInfo       *interface);  void                node_info_add_node            (NodeInfo            *info,                                                     NodeInfo            *child); +void                node_info_replace_node        (NodeInfo            *info, +                                                   NodeInfo            *old_child, +                                                   NodeInfo            *new_child);  InterfaceInfo*      interface_info_new            (const char          *name);  InterfaceInfo*      interface_info_ref            (InterfaceInfo       *info);  void                interface_info_unref          (InterfaceInfo       *info); diff --git a/glib/dbus-gloader-expat.c b/glib/dbus-gloader-expat.c index fa7e3692..609f3164 100644 --- a/glib/dbus-gloader-expat.c +++ b/glib/dbus-gloader-expat.c @@ -23,6 +23,7 @@  #include "dbus-gparser.h"  #include <expat.h> +#include <string.h>  static void*  expat_g_malloc (size_t sz) @@ -192,6 +193,9 @@ description_load_from_string (const char  *str,    g_return_val_if_fail (error == NULL || *error == NULL, NULL); +  if (len < 0) +    len = strlen (str); +      expat = NULL;    context.parser = NULL;    context.error = error; diff --git a/glib/dbus-gobject.c b/glib/dbus-gobject.c index f08bf39e..245ebf1e 100644 --- a/glib/dbus-gobject.c +++ b/glib/dbus-gobject.c @@ -289,26 +289,28 @@ handle_introspect (DBusConnection *connection,    xml = g_string_new (NULL); +  g_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE); +      g_string_append (xml, "<node>\n");    /* We are introspectable, though I guess that was pretty obvious */    g_string_append (xml, "  <interface name=\"org.freedesktop.Introspectable\">\n");    g_string_append (xml, "    <method name=\"Introspect\">\n"); -  g_string_append (xml, "      <arg name=\"data\" direction=\"out\" type=\"string\"\"/>\n"); +  g_string_append (xml, "      <arg name=\"data\" direction=\"out\" type=\"string\"/>\n");    g_string_append (xml, "    </method>\n");    g_string_append (xml, "  </interface>\n");    /* We support get/set properties */    g_string_append (xml, "  <interface name=\"org.freedesktop.Properties\">\n");    g_string_append (xml, "    <method name=\"Get\">\n"); -  g_string_append (xml, "      <arg name=\"interface\" direction=\"in\" type=\"string\"\"/>\n"); -  g_string_append (xml, "      <arg name=\"propname\" direction=\"in\" type=\"string\"\"/>\n"); -  g_string_append (xml, "      <arg name=\"value\" direction=\"out\" type=\"variant\"\"/>\n"); +  g_string_append (xml, "      <arg name=\"interface\" direction=\"in\" type=\"string\"/>\n"); +  g_string_append (xml, "      <arg name=\"propname\" direction=\"in\" type=\"string\"/>\n"); +  g_string_append (xml, "      <arg name=\"value\" direction=\"out\" type=\"variant\"/>\n");    g_string_append (xml, "    </method>\n");    g_string_append (xml, "    <method name=\"Set\">\n"); -  g_string_append (xml, "      <arg name=\"interface\" direction=\"in\" type=\"string\"\"/>\n"); -  g_string_append (xml, "      <arg name=\"propname\" direction=\"in\" type=\"string\"\"/>\n"); -  g_string_append (xml, "      <arg name=\"value\" direction=\"in\" type=\"variant\"\"/>\n"); +  g_string_append (xml, "      <arg name=\"interface\" direction=\"in\" type=\"string\"/>\n"); +  g_string_append (xml, "      <arg name=\"propname\" direction=\"in\" type=\"string\"/>\n"); +  g_string_append (xml, "      <arg name=\"value\" direction=\"in\" type=\"variant\"/>\n");    g_string_append (xml, "    </method>\n");    g_string_append (xml, "  </interface>\n"); diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index 624a95ca..39f8ba86 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -1032,12 +1032,31 @@ dbus_g_proxy_new_for_peer (DBusGConnection          *connection,    g_return_val_if_fail (interface_name != NULL, NULL);    proxy = dbus_g_proxy_new (connection, NULL, -                           path_name, interface_name); +                            path_name, interface_name);    return proxy;  }  /** + * Gets the bus name a proxy is bound to (may be #NULL in some cases). + * If you created the proxy with dbus_g_proxy_new_for_name(), then + * the name you passed to that will be returned. + * If you created it with dbus_g_proxy_new_for_name_owner(), then the + * unique connection name will be returned. If you created it + * with dbus_g_proxy_new_for_peer() then #NULL will be returned. + * + * @param proxy the proxy + * @returns the bus name the proxy sends messages to + */ +const char* +dbus_g_proxy_get_bus_name (DBusGProxy        *proxy) +{ +  g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), NULL); + +  return proxy->name; +} + +/**   * Invokes a method on a remote interface. This function does not   * block; instead it returns an opaque #DBusPendingCall object that   * tracks the pending call.  The method call will not be sent over the @@ -1113,23 +1132,28 @@ dbus_g_proxy_begin_call (DBusGProxy *proxy,   *   * Otherwise, the "out" parameters and return value of the   * method are stored in the provided varargs list. - * The list should be terminated with DBUS_TYPE_INVALID. + * The list should be terminated with #DBUS_TYPE_INVALID.   *   * This function doesn't affect the reference count of the   * #DBusPendingCall, the caller of dbus_g_proxy_begin_call() still owns   * a reference.   * + * @todo this should be changed to make a g_malloc() copy of the + * data returned probably; right now the data vanishes + * when you free the PendingCall which is sort of strange. + *   * @param proxy a proxy for a remote interface   * @param pending the pending call from dbus_g_proxy_begin_call()   * @param error return location for an error   * @param first_arg_type type of first "out" argument - * @returns #FALSE if an error is set */ + * @returns #FALSE if an error is set + */  gboolean  dbus_g_proxy_end_call (DBusGProxy          *proxy, -                      DBusGPendingCall    *pending, -                      GError             **error, -                      int                  first_arg_type, -                      ...) +                       DBusGPendingCall    *pending, +                       GError             **error, +                       int                  first_arg_type, +                       ...)  {    DBusMessage *message;    va_list args; @@ -1223,6 +1247,30 @@ dbus_g_proxy_call_no_reply (DBusGProxy               *proxy,  }  /** + * Increments refcount on a pending call. + * + * @param call the call + * @returns the same call + */ +DBusGPendingCall* +dbus_g_pending_call_ref (DBusGPendingCall  *call) +{ +  dbus_pending_call_ref (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (call)); +  return call; +} + +/** + * Decrements refcount on a pending call. + * + * @param call the call + */ +void +dbus_g_pending_call_unref (DBusGPendingCall  *call) +{ +  dbus_pending_call_unref (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (call)); +} + +/**   * Sends a message to the interface we're proxying for.  Does not   * block or wait for a reply. The message is only actually written out   * when you return to the main loop or block in diff --git a/glib/dbus-gutils.c b/glib/dbus-gutils.c index ff48e7f1..cf12245c 100644 --- a/glib/dbus-gutils.c +++ b/glib/dbus-gutils.c @@ -39,19 +39,25 @@ _dbus_gutils_split_path (const char *path)    len = strlen (path);    n_components = 0; -  i = 0; -  while (i < len) +  if (path[1] != '\0') /* if not "/" */      { -      if (path[i] == '/') -        n_components += 1; -      ++i; +      i = 0; +      while (i < len) +        { +          if (path[i] == '/') +            n_components += 1; +          ++i; +        }      }    split = g_new0 (char*, n_components + 1);    comp = 0; -  i = 0; -  while (i < len) +  if (n_components == 0) +    i = 1; +  else +    i = 0; +  while (comp < n_components)      {        if (path[i] == '/')          ++i; diff --git a/test/glib/run-test.sh b/test/glib/run-test.sh index eddea5f8..0a5e3f65 100755 --- a/test/glib/run-test.sh +++ b/test/glib/run-test.sh @@ -57,12 +57,21 @@ echo "Started test bus pid $DBUS_SESSION_BUS_PID at $DBUS_SESSION_BUS_ADDRESS"  export DBUS_TEST_GLIB_RUN_TEST_SCRIPT=1  if test x$MODE = xprofile ; then +  echo "profiling type $PROFILE_TYPE"    sleep 2 ## this lets the bus get started so its startup time doesn't affect the profile too much    if test x$PROFILE_TYPE = x ; then        PROFILE_TYPE=all    fi    libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/glib/test-profile $PROFILE_TYPE || die "test-profile failed" +elif test x$MODE = xviewer ; then +  echo "Launching dbus-viewer" +  ARGS= +  if test x$DEBUG = x ; then +      ARGS="--services org.freedesktop.DBus" +  fi +  libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/tools/dbus-viewer $ARGS || die "could not run dbus-viewer"  else +  echo "running test-dbus-glib"    libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/glib/test-dbus-glib || die "test-dbus-glib failed"  fi diff --git a/test/glib/test-service-glib.c b/test/glib/test-service-glib.c index cad6f168..9b1be0ad 100644 --- a/test/glib/test-service-glib.c +++ b/test/glib/test-service-glib.c @@ -4,6 +4,43 @@  #include <stdlib.h>  #include <string.h> +typedef struct MyObject MyObject; +typedef struct MyObjectClass MyObjectClass; + +GType my_object_get_type (void); + +struct MyObject +{ +  GObject parent; +}; + +struct MyObjectClass +{ +  GObjectClass parent; +}; + +#define MY_TYPE_OBJECT              (my_object_get_type ()) +#define MY_OBJECT_OBJECT(object)    (G_TYPE_CHECK_INSTANCE_CAST ((object), MY_TYPE_OBJECT, MyObject)) +#define MY_OBJECT_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), MY_TYPE_OBJECT, MyObjectClass)) +#define MY_IS_OBJECT(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MY_TYPE_OBJECT)) +#define MY_IS_OBJECT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MY_TYPE_OBJECT)) +#define MY_OBJECT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MY_TYPE_OBJECT, MyObjectClass)) + +G_DEFINE_TYPE(MyObject, my_object, G_TYPE_OBJECT) + + +static void +my_object_init (MyObject *obj) +{ +   +} + +static void +my_object_class_init (MyObjectClass *obj_class) +{ +   +} +       static GMainLoop *loop;  int @@ -11,6 +48,7 @@ main (int argc, char **argv)  {    DBusGConnection *connection;    GError *error; +  GObject *obj;    g_type_init (); @@ -27,7 +65,15 @@ main (int argc, char **argv)        exit (1);      } +  obj = g_object_new (MY_TYPE_OBJECT, NULL); + +  dbus_g_connection_register_g_object (connection, +                                       "/org/freedesktop/my_test_object", +                                       obj); +  g_print ("GLib test service entering main loop\n"); + +  g_main_loop_run (loop);    g_print ("Successfully completed %s\n", argv[0]); diff --git a/tools/dbus-viewer.c b/tools/dbus-viewer.c index 9c57b229..c32e6fd9 100644 --- a/tools/dbus-viewer.c +++ b/tools/dbus-viewer.c @@ -29,6 +29,7 @@  #include "dbus-tree-view.h"  #include <glib/dbus-gparser.h>  #include <glib/dbus-gutils.h> +#include <dbus/dbus-glib.h>  #include <libintl.h>  #define _(x) dgettext (GETTEXT_PACKAGE, x) @@ -188,6 +189,133 @@ show_error_dialog (GtkWindow *transient_parent,      }  } +static gboolean +load_child_nodes (const char *service_name, +                  NodeInfo   *parent, +                  GError    **error) +{ +  DBusGConnection *connection; +  GSList *tmp; +   +  connection = dbus_g_bus_get (DBUS_BUS_SESSION, error); +  if (connection == NULL) +    return FALSE; + +  tmp = node_info_get_nodes (parent); +  while (tmp != NULL) +    { +      DBusGProxy *proxy; +      DBusGPendingCall *call; +      const char *data; +      NodeInfo *child; +      NodeInfo *complete_child; + +      complete_child = NULL; +       +      child = tmp->data; + +      g_assert (*service_name == ':'); /* so we don't need new_for_name_owner */ +      proxy = dbus_g_proxy_new_for_name (connection, +                                         service_name, +                                         "/", +                                         DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE); +      g_assert (proxy != NULL); +   +      call = dbus_g_proxy_begin_call (proxy, "Introspect", +                                      DBUS_TYPE_INVALID); +       +      data = NULL; +      if (!dbus_g_proxy_end_call (proxy, call, error, DBUS_TYPE_STRING, &data, +                                  DBUS_TYPE_INVALID)) +        goto done; +       +      complete_child = description_load_from_string (data, -1, error); +      if (complete_child == NULL) +        goto done; +       +    done: +      dbus_g_pending_call_unref (call); +      g_object_unref (proxy); + +      if (complete_child == NULL) +        return FALSE; + +      /* change complete_child's name to relative */ +      base_info_set_name ((BaseInfo*)complete_child, +                          base_info_get_name ((BaseInfo*)child)); +       +      /* Stitch in complete_child rather than child */ +      node_info_replace_node (parent, child, complete_child); +      node_info_unref (complete_child); /* ref still held by parent */ +       +      /* Now recurse */ +      if (!load_child_nodes (service_name, complete_child, error)) +        return FALSE; +       +      tmp = tmp->next; +    } + +  return TRUE; +} + +static NodeInfo* +load_from_service (const char *service_name, +                   GError    **error) +{ +  DBusGConnection *connection; +  DBusGProxy *root_proxy; +  DBusGPendingCall *call; +  const char *data; +  NodeInfo *node; + +  node = NULL; +  call = NULL; +   +  connection = dbus_g_bus_get (DBUS_BUS_SESSION, error); +  if (connection == NULL) +    return NULL; + +  root_proxy = dbus_g_proxy_new_for_name_owner (connection, +                                                service_name, +                                                "/", +                                                DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE, +                                                error); +  if (root_proxy == NULL) +    return NULL; +   +  call = dbus_g_proxy_begin_call (root_proxy, "Introspect", +                                  DBUS_TYPE_INVALID); + +  data = NULL; +  if (!dbus_g_proxy_end_call (root_proxy, call, error, DBUS_TYPE_STRING, &data, +                              DBUS_TYPE_INVALID)) +    goto out; + +  node = description_load_from_string (data, -1, error); + +  /* g_print ("%s\n", data); */ +   +  if (node == NULL) +    goto out; + +  base_info_set_name ((BaseInfo*)node, "/"); +   +  if (!load_child_nodes (dbus_g_proxy_get_bus_name (root_proxy), +                         node, error)) +    { +      node_info_unref (node); +      node = NULL; +      goto out; +    } +   + out: +  if (call) +    dbus_g_pending_call_unref (call); +     +  g_object_unref (root_proxy); +  return node; +} +  static void  usage (int ecode)  { @@ -214,6 +342,7 @@ main (int argc, char **argv)    GSList *files;    gboolean end_of_args;    GSList *tmp; +  gboolean services;    bindtextdomain (GETTEXT_PACKAGE, DBUS_LOCALEDIR);    bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); @@ -221,6 +350,7 @@ main (int argc, char **argv)    gtk_init (&argc, &argv); +  services = FALSE;    end_of_args = FALSE;    files = NULL;    prev_arg = NULL; @@ -237,6 +367,8 @@ main (int argc, char **argv)              usage (0);            else if (strcmp (arg, "--version") == 0)              version (); +          else if (strcmp (arg, "--services") == 0) +            services = TRUE;            else if (arg[0] == '-' &&                     arg[1] == '-' &&                     arg[2] == '\0') @@ -270,8 +402,12 @@ main (int argc, char **argv)        filename = tmp->data;        error = NULL; -      node = description_load_from_file (filename, -                                         &error); +      if (services) +        node = load_from_service (filename, &error); +      else +        node = description_load_from_file (filename, +                                           &error); +              if (node == NULL)          {            g_assert (error != NULL); @@ -313,8 +449,3 @@ main (int argc, char **argv)    return 0;  } - - - - -  | 
