2003-10-16 Havoc Pennington <hp@redhat.com>
authorHavoc Pennington <hp@redhat.com>
Thu, 16 Oct 2003 06:34:51 +0000 (06:34 +0000)
committerHavoc Pennington <hp@redhat.com>
Thu, 16 Oct 2003 06:34:51 +0000 (06:34 +0000)
* bus/connection.c (bus_pending_reply_expired): either cancel or
execute, not both
(bus_connections_check_reply): use unlink, not remove_link, as we
don't want to free the link; fixes double free mess

* dbus/dbus-pending-call.c (dbus_pending_call_block): fix in case
where no reply was received

* dbus/dbus-connection.c (_dbus_pending_call_complete_and_unlock):
fix a refcount leak

* bus/signals.c (match_rule_matches): add special cases for the
bus driver, so you can match on sender/destination for it.

* dbus/dbus-sysdeps.c (_dbus_abort): print backtrace if
DBUS_PRINT_BACKTRACE is set

* dbus/dbus-internals.c: add pid to assertion failure messages

* dbus/dbus-connection.c: add message type code to the debug spew

* glib/dbus-gproxy.c (gproxy_get_match_rule): match rules want
sender=foo not service=foo

* dbus/dbus-bus.c (dbus_bus_get): if the activation bus is the
session bus but DBUS_SESSION_BUS_ADDRESS isn't set, use
DBUS_ACTIVATION_ADDRESS instead

* bus/activation.c: set DBUS_SESSION_BUS_ADDRESS,
DBUS_SYSTEM_BUS_ADDRESS if appropriate

* bus/bus.c (bus_context_new): handle OOM copying bus type into
context struct

* dbus/dbus-message.c (dbus_message_iter_get_object_path): new function
(dbus_message_iter_get_object_path_array): new function (half
finished, disabled for the moment)

* glib/dbus-gproxy.c (dbus_gproxy_end_call): properly handle
DBUS_MESSAGE_TYPE_ERROR

* tools/dbus-launch.c (babysit): support DBUS_DEBUG_OUTPUT to
avoid redirecting stderr to /dev/null
(babysit): close stdin if not doing the "exit_with_session" thing

* dbus/dbus-sysdeps.c (_dbus_become_daemon): delete some leftover
debug code; change DBUS_DEBUG_OUTPUT to only enable stderr, not
stdout/stdin, so things don't get confused

* bus/system.conf.in: fix to allow replies, I modified .conf
instead of .conf.in again.

20 files changed:
ChangeLog
bus/activation.c
bus/bus.c
bus/connection.c
bus/signals.c
bus/system.conf.in
dbus/dbus-bus.c
dbus/dbus-connection.c
dbus/dbus-internals.c
dbus/dbus-internals.h
dbus/dbus-message.c
dbus/dbus-message.h
dbus/dbus-pending-call.c
dbus/dbus-sysdeps.c
doc/TODO
glib/dbus-gproxy.c
test/glib/run-test.sh
test/glib/test-dbus-glib.c
test/test-service.c
tools/dbus-launch.c

index deb3748..7f650ff 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,57 @@
+2003-10-16  Havoc Pennington  <hp@redhat.com>
+
+       * bus/connection.c (bus_pending_reply_expired): either cancel or
+       execute, not both
+       (bus_connections_check_reply): use unlink, not remove_link, as we
+       don't want to free the link; fixes double free mess
+
+       * dbus/dbus-pending-call.c (dbus_pending_call_block): fix in case
+       where no reply was received
+
+       * dbus/dbus-connection.c (_dbus_pending_call_complete_and_unlock):
+       fix a refcount leak
+
+       * bus/signals.c (match_rule_matches): add special cases for the
+       bus driver, so you can match on sender/destination for it.
+
+       * dbus/dbus-sysdeps.c (_dbus_abort): print backtrace if
+       DBUS_PRINT_BACKTRACE is set
+
+       * dbus/dbus-internals.c: add pid to assertion failure messages
+
+       * dbus/dbus-connection.c: add message type code to the debug spew
+
+       * glib/dbus-gproxy.c (gproxy_get_match_rule): match rules want
+       sender=foo not service=foo
+
+       * dbus/dbus-bus.c (dbus_bus_get): if the activation bus is the
+       session bus but DBUS_SESSION_BUS_ADDRESS isn't set, use 
+       DBUS_ACTIVATION_ADDRESS instead
+
+       * bus/activation.c: set DBUS_SESSION_BUS_ADDRESS,
+       DBUS_SYSTEM_BUS_ADDRESS if appropriate
+
+       * bus/bus.c (bus_context_new): handle OOM copying bus type into
+       context struct
+
+       * dbus/dbus-message.c (dbus_message_iter_get_object_path): new function
+       (dbus_message_iter_get_object_path_array): new function (half
+       finished, disabled for the moment)
+       
+       * glib/dbus-gproxy.c (dbus_gproxy_end_call): properly handle
+       DBUS_MESSAGE_TYPE_ERROR
+
+       * tools/dbus-launch.c (babysit): support DBUS_DEBUG_OUTPUT to
+       avoid redirecting stderr to /dev/null
+       (babysit): close stdin if not doing the "exit_with_session" thing
+
+       * dbus/dbus-sysdeps.c (_dbus_become_daemon): delete some leftover
+       debug code; change DBUS_DEBUG_OUTPUT to only enable stderr, not
+       stdout/stdin, so things don't get confused
+       
+       * bus/system.conf.in: fix to allow replies, I modified .conf
+       instead of .conf.in again.
+
 2003-10-14  David Zeuthen  <david@fubar.dk>
 
        * python/dbus_bindings.pyx.in (MessageIter.get): fixed typo in
index 91d3c11..5588ed8 100644 (file)
@@ -482,12 +482,25 @@ child_setup (void *data)
    */
   if (!_dbus_setenv ("DBUS_ACTIVATION_ADDRESS", activation->server_address))
     _dbus_exit (1);
-
+  
   type = bus_context_get_type (activation->context);
   if (type != NULL)
     {
       if (!_dbus_setenv ("DBUS_BUS_TYPE", type))
         _dbus_exit (1);
+
+      if (strcmp (type, "session") == 0)
+        {
+          if (!_dbus_setenv ("DBUS_SESSION_BUS_ADDRESS",
+                             activation->server_address))
+            _dbus_exit (1);
+        }
+      else if (strcmp (type, "system") == 0)
+        {
+          if (!_dbus_setenv ("DBUS_SYSTEM_BUS_ADDRESS",
+                             activation->server_address))
+            _dbus_exit (1);
+        }
     }
 }
 
index a00201a..91c9e6a 100644 (file)
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -37,6 +37,7 @@ struct BusContext
 {
   int refcount;
   char *type;
+  char *bus_env_var;
   char *address;
   char *pidfile;
   DBusLoop *loop;
@@ -398,6 +399,11 @@ bus_context_new (const DBusString *config_file,
 
   /* note that type may be NULL */
   context->type = _dbus_strdup (bus_config_parser_get_type (parser));
+  if (bus_config_parser_get_type (parser) != NULL && context->type == NULL)
+    {
+      BUS_SET_OOM (error);
+      goto failed;
+    }
   
   /* We have to build the address backward, so that
    * <listen> later in the config file have priority
index 1e56242..65ebdb2 100644 (file)
@@ -54,7 +54,7 @@ struct BusConnections
   BusContext *context;
   DBusHashTable *completed_by_user; /**< Number of completed connections for each UID */
   DBusTimeout *expire_timeout; /**< Timeout for expiring incomplete connections. */
-  int stamp;            /**< Incrementing number */
+  int stamp;                   /**< Incrementing number */
   BusExpireList *pending_replies; /**< List of pending replies */
 };
 
@@ -1340,6 +1340,18 @@ bus_connections_check_limits (BusConnections  *connections,
   return TRUE;
 }
 
+static void
+bus_pending_reply_free (BusPendingReply *pending)
+{
+  _dbus_verbose ("Freeing pending reply %p, replier %p receiver %p serial %u\n",
+                 pending,
+                 pending->will_send_reply,
+                 pending->will_get_reply,
+                 pending->reply_serial);
+
+  dbus_free (pending);
+}
+
 static dbus_bool_t
 bus_pending_reply_send_no_reply (BusConnections  *connections,
                                  BusTransaction  *transaction,
@@ -1393,20 +1405,28 @@ bus_pending_reply_expired (BusExpireList *list,
    * leave it in the list to try expiring again later when we
    * get more memory.
    */
+
+  _dbus_verbose ("Expiring pending reply %p, replier %p receiver %p serial %u\n",
+                 pending,
+                 pending->will_send_reply,
+                 pending->will_get_reply,
+                 pending->reply_serial);
+  
   transaction = bus_transaction_new (connections->context);
   if (transaction == NULL)
     return;
   
-  if (bus_pending_reply_send_no_reply (connections,
-                                       transaction,
-                                       pending))
+  if (!bus_pending_reply_send_no_reply (connections,
+                                        transaction,
+                                        pending))
     {
-      _dbus_list_remove_link (&connections->pending_replies->items,
-                              link);
-      dbus_free (pending);
       bus_transaction_cancel_and_free (transaction);
+      return;
     }
-
+  
+  _dbus_list_remove_link (&connections->pending_replies->items,
+                          link);
+  bus_pending_reply_free (pending);
   bus_transaction_execute_and_free (transaction);
 }
 
@@ -1418,6 +1438,9 @@ bus_connection_drop_pending_replies (BusConnections  *connections,
    * do anything with it except check for pointer equality
    */
   DBusList *link;
+
+  _dbus_verbose ("Dropping pending replies that involve connection %p\n",
+                 connection);
   
   link = _dbus_list_get_first_link (&connections->pending_replies->items);
   while (link != NULL)
@@ -1433,16 +1456,27 @@ bus_connection_drop_pending_replies (BusConnections  *connections,
         {
           /* We don't need to track this pending reply anymore */
 
+          _dbus_verbose ("Dropping pending reply %p, replier %p receiver %p serial %u\n",
+                         pending,
+                         pending->will_send_reply,
+                         pending->will_get_reply,
+                         pending->reply_serial);
+          
           _dbus_list_remove_link (&connections->pending_replies->items,
                                   link);
-          dbus_free (pending);
+          bus_pending_reply_free (pending);
         }
       else if (pending->will_send_reply == connection)
         {
           /* The reply isn't going to be sent, so set things
            * up so it will be expired right away
            */
-
+          _dbus_verbose ("Will expire pending reply %p, replier %p receiver %p serial %u\n",
+                         pending,
+                         pending->will_send_reply,
+                         pending->will_get_reply,
+                         pending->reply_serial);
+          
           pending->will_send_reply = NULL;
           pending->expire_item.added_tv_sec = 0;
           pending->expire_item.added_tv_usec = 0;
@@ -1467,11 +1501,13 @@ cancel_pending_reply (void *data)
 {
   CancelPendingReplyData *d = data;
 
+  _dbus_verbose ("%s: d = %p\n", _DBUS_FUNCTION_NAME, d);
+  
   if (!_dbus_list_remove (&d->connections->pending_replies->items,
                           d->pending))
     _dbus_assert_not_reached ("pending reply did not exist to be cancelled");
 
-  dbus_free (d->pending); /* since it's been cancelled */
+  bus_pending_reply_free (d->pending); /* since it's been cancelled */
 }
 
 static void
@@ -1479,6 +1515,8 @@ cancel_pending_reply_data_free (void *data)
 {
   CancelPendingReplyData *d = data;
 
+  _dbus_verbose ("%s: d = %p\n", _DBUS_FUNCTION_NAME, d);
+  
   /* d->pending should be either freed or still
    * in the list of pending replies (owned by someone
    * else)
@@ -1537,11 +1575,21 @@ bus_connections_expect_reply (BusConnections  *connections,
       return FALSE;
     }
 
+#ifdef DBUS_ENABLE_VERBOSE_MODE
+  /* so we can see a not-yet-added pending reply */
+  pending->expire_item.added_tv_sec = 1;
+  pending->expire_item.added_tv_usec = 1;
+#endif
+
+  pending->will_get_reply = will_get_reply;
+  pending->will_send_reply = will_send_reply;
+  pending->reply_serial = reply_serial;
+  
   cprd = dbus_new0 (CancelPendingReplyData, 1);
   if (cprd == NULL)
     {
       BUS_SET_OOM (error);
-      dbus_free (pending);
+      bus_pending_reply_free (pending);
       return FALSE;
     }
   
@@ -1550,7 +1598,7 @@ bus_connections_expect_reply (BusConnections  *connections,
     {
       BUS_SET_OOM (error);
       dbus_free (cprd);
-      dbus_free (pending);
+      bus_pending_reply_free (pending);
       return FALSE;
     }
 
@@ -1562,7 +1610,7 @@ bus_connections_expect_reply (BusConnections  *connections,
       BUS_SET_OOM (error);
       _dbus_list_remove (&connections->pending_replies->items, pending);
       dbus_free (cprd);
-      dbus_free (pending);
+      bus_pending_reply_free (pending);
       return FALSE;
     }
                                         
@@ -1572,10 +1620,12 @@ bus_connections_expect_reply (BusConnections  *connections,
   _dbus_get_current_time (&pending->expire_item.added_tv_sec,
                           &pending->expire_item.added_tv_usec);
 
-  pending->will_get_reply = will_get_reply;
-  pending->will_send_reply = will_send_reply;
-  pending->reply_serial = reply_serial;
-
+  _dbus_verbose ("Added pending reply %p, replier %p receiver %p serial %u\n",
+                 pending,
+                 pending->will_send_reply,
+                 pending->will_get_reply,
+                 pending->reply_serial);
+  
   return TRUE;
 }
 
@@ -1590,6 +1640,8 @@ cancel_check_pending_reply (void *data)
 {
   CheckPendingReplyData *d = data;
 
+  _dbus_verbose ("%s: d = %p\n", _DBUS_FUNCTION_NAME, d);
+  
   _dbus_list_prepend_link (&d->connections->pending_replies->items,
                            d->link);
   d->link = NULL;
@@ -1600,11 +1652,16 @@ check_pending_reply_data_free (void *data)
 {
   CheckPendingReplyData *d = data;
 
+  _dbus_verbose ("%s: d = %p\n", _DBUS_FUNCTION_NAME, d);
+  
   if (d->link != NULL)
     {
       BusPendingReply *pending = d->link->data;
-
-      dbus_free (pending);
+      
+      _dbus_assert (_dbus_list_find_last (&d->connections->pending_replies->items,
+                                          pending) == NULL);
+      
+      bus_pending_reply_free (pending);
       _dbus_list_free_link (d->link);
     }
   
@@ -1641,7 +1698,7 @@ bus_connections_check_reply (BusConnections *connections,
           pending->will_get_reply == receiving_reply &&
           pending->will_send_reply == sending_reply)
         {
-          _dbus_verbose ("Found pending reply\n");
+          _dbus_verbose ("Found pending reply with serial %u\n", reply_serial);
           break;
         }
       
@@ -1676,8 +1733,11 @@ bus_connections_check_reply (BusConnections *connections,
   cprd->link = link;
   cprd->connections = connections;
   
-  _dbus_list_remove_link (&connections->pending_replies->items,
-                          link);
+  _dbus_list_unlink (&connections->pending_replies->items,
+                     link);
+  
+  _dbus_assert (_dbus_list_find_last (&connections->pending_replies->items,
+                                      link->data) == NULL);
 
   return TRUE;
 }
@@ -2075,6 +2135,9 @@ bus_transaction_add_cancel_hook (BusTransaction               *transaction,
   ch = dbus_new (CancelHook, 1);
   if (ch == NULL)
     return FALSE;
+
+  _dbus_verbose ("     adding cancel hook function = %p data = %p\n",
+                 cancel_function, data);
   
   ch->cancel_function = cancel_function;
   ch->data = data;
index 0fd4b51..9c0d31e 100644 (file)
@@ -1006,6 +1006,8 @@ connection_is_primary_owner (DBusConnection *connection,
   DBusString str;
   BusRegistry *registry;
 
+  _dbus_assert (connection != NULL);
+  
   registry = bus_connection_get_registry (connection);
 
   _dbus_string_init_const (&str, service_name);
@@ -1028,6 +1030,11 @@ match_rule_matches (BusMatchRule    *rule,
    * so FALSE if any of them don't match.
    */
 
+  /* sender/addressed_recipient of #NULL may mean bus driver,
+   * or for addressed_recipient may mean a message with no
+   * specific recipient (i.e. a signal)
+   */
+  
   if (rule->flags & BUS_MATCH_MESSAGE_TYPE)
     {
       _dbus_assert (rule->message_type != DBUS_MESSAGE_TYPE_INVALID);
@@ -1068,8 +1075,17 @@ match_rule_matches (BusMatchRule    *rule,
     {
       _dbus_assert (rule->sender != NULL);
 
-      if (!connection_is_primary_owner (sender, rule->sender))
-        return FALSE;
+      if (sender == NULL)
+        {
+          if (strcmp (rule->sender,
+                      DBUS_SERVICE_ORG_FREEDESKTOP_DBUS) != 0)
+            return FALSE;
+        }
+      else
+        {
+          if (!connection_is_primary_owner (sender, rule->sender))
+            return FALSE;
+        }
     }
 
   if (rule->flags & BUS_MATCH_DESTINATION)
@@ -1078,15 +1094,21 @@ match_rule_matches (BusMatchRule    *rule,
 
       _dbus_assert (rule->destination != NULL);
 
-      if (addressed_recipient == NULL)
-        return FALSE;
-
       destination = dbus_message_get_destination (message);
       if (destination == NULL)
         return FALSE;
 
-      if (!connection_is_primary_owner (addressed_recipient, rule->destination))
-        return FALSE;
+      if (addressed_recipient == NULL)
+        {          
+          if (strcmp (rule->destination,
+                      DBUS_SERVICE_ORG_FREEDESKTOP_DBUS) != 0)
+            return FALSE;
+        }
+      else
+        {
+          if (!connection_is_primary_owner (addressed_recipient, rule->destination))
+            return FALSE;
+        }
     }
 
   if (rule->flags & BUS_MATCH_PATH)
index 8e2dbda..167ac39 100644 (file)
@@ -44,6 +44,8 @@
          even if they aren't in here -->
     <allow send_destination="org.freedesktop.DBus"/>
     <allow receive_sender="org.freedesktop.DBus"/>
+    <!-- valid replies are always allowed -->
+    <allow requested_reply="true"/>
   </policy>
 
   <!-- Config files are placed here that among other things, punch 
index 0c9f58e..58df18d 100644 (file)
@@ -143,6 +143,8 @@ init_connections_unlocked (void)
       
        if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
          {
+           _dbus_verbose ("Filling in system bus address...\n");
+           
            if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
                               "DBUS_SYSTEM_BUS_ADDRESS"))
              return FALSE;
@@ -154,27 +156,44 @@ init_connections_unlocked (void)
                  _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
                if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
                  return FALSE;
+
+               _dbus_verbose ("  used default system bus \"%s\"\n",
+                              bus_connection_addresses[DBUS_BUS_SYSTEM]);
              }
+           else
+             _dbus_verbose ("  used env var system bus \"%s\"\n",
+                            bus_connection_addresses[DBUS_BUS_SYSTEM]);
          }
           
       if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
         {
+          _dbus_verbose ("Filling in session bus address...\n");
+          
           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION],
                              "DBUS_SESSION_BUS_ADDRESS"))
             return FALSE;
+          _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
+                         bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
         }
 
       if (bus_connection_addresses[DBUS_BUS_ACTIVATION] == NULL)
         {
+          _dbus_verbose ("Filling in activation bus address...\n");
+          
           if (!get_from_env (&bus_connection_addresses[DBUS_BUS_ACTIVATION],
                              "DBUS_ACTIVATION_ADDRESS"))
             return FALSE;
+
+          _dbus_verbose ("  \"%s\"\n", bus_connection_addresses[DBUS_BUS_ACTIVATION] ?
+                         bus_connection_addresses[DBUS_BUS_ACTIVATION] : "none set");
         }
 
       s = _dbus_getenv ("DBUS_ACTIVATION_BUS_TYPE");
 
       if (s != NULL)
         {
+          _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
+          
           if (strcmp (s, "system") == 0)
             activation_bus_type = DBUS_BUS_SYSTEM;
           else if (strcmp (s, "session") == 0)
@@ -311,10 +330,12 @@ dbus_bus_get (DBusBusType  type,
   address_type = type;
   
   /* Use the real type of the activation bus for getting its
-   * connection. (If the activating bus isn't a well-known
-   * bus then activation_bus_type == DBUS_BUS_ACTIVATION)
+   * connection, but only if the real type's address is available. (If
+   * the activating bus isn't a well-known bus then
+   * activation_bus_type == DBUS_BUS_ACTIVATION)
    */
-  if (type == DBUS_BUS_ACTIVATION)
+  if (type == DBUS_BUS_ACTIVATION &&
+      bus_connection_addresses[activation_bus_type] != NULL)
     type = activation_bus_type;
   
   if (bus_connections[type] != NULL)
index ed7d57d..bceef2a 100644 (file)
@@ -344,11 +344,13 @@ _dbus_connection_queue_received_message_link (DBusConnection  *connection,
 
   _dbus_connection_wakeup_mainloop (connection);
   
-  _dbus_verbose ("Message %p (%s) added to incoming queue %p, %d incoming\n",
+  _dbus_verbose ("Message %p (%d %s '%s') added to incoming queue %p, %d incoming\n",
                  message,
+                 dbus_message_get_type (message),
                  dbus_message_get_interface (message) ?
                  dbus_message_get_interface (message) :
                  "no interface",
+                 dbus_message_get_signature (message),
                  connection,
                  connection->n_incoming);
 }
@@ -430,11 +432,13 @@ _dbus_connection_message_sent (DBusConnection *connection,
   
   connection->n_outgoing -= 1;
 
-  _dbus_verbose ("Message %p (%s) removed from outgoing queue %p, %d left to send\n",
+  _dbus_verbose ("Message %p (%d %s '%s') removed from outgoing queue %p, %d left to send\n",
                  message,
+                 dbus_message_get_type (message),
                  dbus_message_get_interface (message) ?
                  dbus_message_get_interface (message) :
                  "no interface",
+                 dbus_message_get_signature (message),
                  connection, connection->n_outgoing);
 
   /* Save this link in the link cache also */
@@ -690,12 +694,20 @@ _dbus_pending_call_complete_and_unlock (DBusPendingCall *pending,
       message = pending->timeout_link->data;
       _dbus_list_clear (&pending->timeout_link);
     }
+  else
+    dbus_message_ref (message);
 
-  _dbus_verbose ("  handing message %p to pending call\n", message);
+  _dbus_verbose ("  handing message %p (%s) to pending call serial %u\n",
+                 message,
+                 dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN ?
+                 "method return" :
+                 dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR ?
+                 "error" : "other type",
+                 pending->reply_serial);
   
   _dbus_assert (pending->reply == NULL);
+  _dbus_assert (pending->reply_serial == dbus_message_get_reply_serial (message));
   pending->reply = message;
-  dbus_message_ref (pending->reply);
   
   dbus_pending_call_ref (pending); /* in case there's no app with a ref held */
   _dbus_connection_detach_pending_call_and_unlock (pending->connection, pending);
@@ -1505,11 +1517,13 @@ _dbus_connection_send_preallocated_unlocked (DBusConnection       *connection,
   
   connection->n_outgoing += 1;
 
-  _dbus_verbose ("Message %p (%s) added to outgoing queue %p, %d pending to send\n",
+  _dbus_verbose ("Message %p (%d %s '%s') added to outgoing queue %p, %d pending to send\n",
                  message,
+                 dbus_message_get_type (message),
                  dbus_message_get_interface (message) ?
                  dbus_message_get_interface (message) :
                  "no interface",
+                 dbus_message_get_signature (message),
                  connection,
                  connection->n_outgoing);
 
@@ -2178,11 +2192,13 @@ _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
       link = _dbus_list_pop_first_link (&connection->incoming_messages);
       connection->n_incoming -= 1;
 
-      _dbus_verbose ("Message %p (%s) removed from incoming queue %p, %d incoming\n",
+      _dbus_verbose ("Message %p (%d %s '%s') removed from incoming queue %p, %d incoming\n",
                      link->data,
+                     dbus_message_get_type (link->data),
                      dbus_message_get_interface (link->data) ?
                      dbus_message_get_interface (link->data) :
                      "no interface",
+                     dbus_message_get_signature (link->data),
                      connection, connection->n_incoming);
 
       return link;
@@ -2227,11 +2243,13 @@ _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
                            message_link);
   connection->n_incoming += 1;
 
-  _dbus_verbose ("Message %p (%s) put back into queue %p, %d incoming\n",
+  _dbus_verbose ("Message %p (%d %s '%s') put back into queue %p, %d incoming\n",
                  message_link->data,
+                 dbus_message_get_type (message_link->data),
                  dbus_message_get_interface (message_link->data) ?
                  dbus_message_get_interface (message_link->data) :
                  "no interface",
+                 dbus_message_get_signature (message_link->data),
                  connection, connection->n_incoming);
 }
 
@@ -2558,8 +2576,9 @@ dbus_connection_dispatch (DBusConnection *connection)
   /* We're still protected from dispatch() reentrancy here
    * since we acquired the dispatcher
    */
-  _dbus_verbose ("  running object path dispatch on message %p (%s)\n",
+  _dbus_verbose ("  running object path dispatch on message %p (%d %s '%s')\n",
                  message,
+                 dbus_message_get_type (message),
                  dbus_message_get_interface (message) ?
                  dbus_message_get_interface (message) :
                  "no interface");
@@ -2625,15 +2644,19 @@ dbus_connection_dispatch (DBusConnection *connection)
       result = DBUS_HANDLER_RESULT_HANDLED;
     }
   
-  _dbus_verbose ("  done dispatching %p (%s) on connection %p\n", message,
+  _dbus_verbose ("  done dispatching %p (%d %s '%s') on connection %p\n", message,
+                 dbus_message_get_type (message),
                  dbus_message_get_interface (message) ?
                  dbus_message_get_interface (message) :
                  "no interface",
+                 dbus_message_get_signature (message),
                  connection);
   
  out:
   if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
     {
+      _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME);
+      
       /* Put message back, and we'll start over.
        * Yes this means handlers must be idempotent if they
        * don't return HANDLED; c'est la vie.
@@ -2643,6 +2666,8 @@ dbus_connection_dispatch (DBusConnection *connection)
     }
   else
     {
+      _dbus_verbose ("Done with message in %s\n", _DBUS_FUNCTION_NAME);
+      
       if (connection->exit_on_disconnect &&
           dbus_message_is_signal (message,
                                   DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
index 44f3ff4..9a2aa2b 100644 (file)
@@ -223,6 +223,8 @@ _dbus_verbose_real (const char *format,
   va_start (args, format);
   vfprintf (stderr, format, args);
   va_end (args);
+
+  fflush (stderr);
 }
 
 /**
@@ -424,7 +426,7 @@ _dbus_header_field_to_string (int header_field)
 #ifndef DBUS_DISABLE_CHECKS
 /** String used in _dbus_return_if_fail macro */
 const char _dbus_return_if_fail_warning_format[] =
-"Arguments to %s() were incorrect, assertion \"%s\" failed in file %s line %d.\n"
+"%lu: arguments to %s() were incorrect, assertion \"%s\" failed in file %s line %d.\n"
 "This is normally a bug in some application using the D-BUS library.\n";
 #endif
 
@@ -448,8 +450,8 @@ _dbus_real_assert (dbus_bool_t  condition,
 {
   if (!condition)
     {
-      _dbus_warn ("Assertion failed \"%s\" file \"%s\" line %d process %lu\n",
-                  condition_text, file, line, _dbus_getpid ());
+      _dbus_warn ("%lu: assertion failed \"%s\" file \"%s\" line %d\n",
+                  _dbus_getpid (), condition_text, file, line);
       _dbus_abort ();
     }
 }
index fa1ad19..0284da0 100644 (file)
@@ -94,18 +94,18 @@ void _dbus_real_assert_not_reached (const char *explanation,
 #else
 extern const char _dbus_return_if_fail_warning_format[];
 
-#define _dbus_return_if_fail(condition) do {                            \
-  if (!(condition)) {                                                   \
-    _dbus_warn (_dbus_return_if_fail_warning_format,                    \
-                _DBUS_FUNCTION_NAME, #condition, __FILE__, __LINE__);   \
-    return;                                                             \
+#define _dbus_return_if_fail(condition) do {                                            \
+  if (!(condition)) {                                                                   \
+    _dbus_warn (_dbus_return_if_fail_warning_format,                                    \
+                _dbus_getpid (), _DBUS_FUNCTION_NAME, #condition, __FILE__, __LINE__);  \
+    return;                                                                             \
   } } while (0)
 
-#define _dbus_return_val_if_fail(condition, val) do {                   \
-  if (!(condition)) {                                                   \
-    _dbus_warn (_dbus_return_if_fail_warning_format,                    \
-                _DBUS_FUNCTION_NAME, #condition, __FILE__, __LINE__);   \
-    return (val);                                                       \
+#define _dbus_return_val_if_fail(condition, val) do {                                   \
+  if (!(condition)) {                                                                   \
+    _dbus_warn (_dbus_return_if_fail_warning_format,                                    \
+                _dbus_getpid (), _DBUS_FUNCTION_NAME, #condition, __FILE__, __LINE__);  \
+    return (val);                                                                       \
   } } while (0)
 
 #endif /* !DBUS_DISABLE_ASSERT */
index c7e0b8c..4c21946 100644 (file)
@@ -1870,6 +1870,9 @@ dbus_message_append_args_valist (DBusMessage *message,
          if (!dbus_message_iter_append_string (&iter, va_arg (var_args, const char *)))
            goto errorout;
          break;
+        case DBUS_TYPE_OBJECT_PATH:
+
+          break;
        case DBUS_TYPE_NAMED:
          {
            const char *name;
@@ -2540,7 +2543,10 @@ dbus_message_iter_get_arg_type (DBusMessageIter *iter)
   _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID);
 
   if (real->pos >= real->end)
-    return DBUS_TYPE_INVALID;
+    {
+      _dbus_verbose ("  iterator at or beyond end of message\n");
+      return DBUS_TYPE_INVALID;
+    }
 
   pos = dbus_message_iter_get_data_start (real, &type);
   
@@ -2645,6 +2651,36 @@ dbus_message_iter_get_string (DBusMessageIter *iter)
                                  pos, NULL);
 }
 
+#if 0
+/**
+ * @todo FIXME to finish this _dbus_demarshal_object_path() needs
+ * to not explode the path.
+ * 
+ * Returns the object path value that an iterator may point to.
+ * Note that you need to check that the iterator points to
+ * an object path value before using this function.
+ *
+ * @see dbus_message_iter_get_arg_type
+ * @param iter the message iter
+ * @returns the path
+ */
+char *
+dbus_message_iter_get_object_path (DBusMessageIter  *iter)
+{
+  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+  int type, pos;
+
+  _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL);
+
+  pos = dbus_message_iter_get_data_start (real, &type);
+  
+  _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
+
+  return _dbus_demarshal_object_path (&real->message->body, real->message->byte_order,
+                                      pos, NULL);
+}
+#endif
+
 /**
  * Returns the name and data from a named type that an
  * iterator may point to. Note that you need to check that
@@ -3226,7 +3262,7 @@ dbus_message_iter_get_double_array  (DBusMessageIter *iter,
 /**
  * Returns the string array that the iterator may point to.
  * Note that you need to check that the iterator points
- * to a byte array prior to using this function.
+ * to a string array prior to using this function.
  *
  * The returned value is a #NULL-terminated array of strings.
  * Each string is a separate malloc block, and the array
@@ -3262,6 +3298,50 @@ dbus_message_iter_get_string_array (DBusMessageIter *iter,
     return TRUE;
 }
 
+#if 0
+/**
+ * @todo FIXME to implement this _dbus_demarshal_object_path_array()
+ * needs implementing
+ * 
+ * Returns the object path array that the iterator may point to.
+ * Note that you need to check that the iterator points
+ * to an object path array prior to using this function.
+ *
+ * The returned value is a #NULL-terminated array of strings.
+ * Each string is a separate malloc block, and the array
+ * itself is a malloc block. You can free this type of
+ * array with dbus_free_string_array().
+ *
+ * @param iter the iterator
+ * @param value return location for string values
+ * @param len return location for length of byte array
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_get_object_path_array (DBusMessageIter *iter,
+                                         char          ***value,
+                                         int             *len)
+{
+  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
+  int type, pos;
+
+  _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE);
+
+  pos = dbus_message_iter_get_data_start (real, &type);
+  
+  _dbus_assert (type == DBUS_TYPE_ARRAY);
+
+  type = iter_get_array_type (real, NULL);
+  _dbus_assert (type == DBUS_TYPE_OBJECT_PATH);
+
+  if (!_dbus_demarshal_object_path_array (&real->message->body, real->message->byte_order,
+                                          pos, NULL, value, len))
+    return FALSE;
+  else
+    return TRUE;
+}
+#endif
+
 /**
  * Returns the key name fot the dict entry that an iterator
  * may point to. Note that you need to check that the iterator
@@ -3664,6 +3744,8 @@ dbus_message_iter_append_double (DBusMessageIter *iter,
 /**
  * Appends a UTF-8 string to the message.
  *
+ * @todo add return_val_if_fail(UTF-8 is valid)
+ *
  * @param iter an iterator pointing to the end of the message
  * @param value the string
  * @returns #TRUE on success
@@ -3675,7 +3757,7 @@ dbus_message_iter_append_string (DBusMessageIter *iter,
   DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
 
   _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE);
-
+  
   if (!dbus_message_iter_append_type (real, DBUS_TYPE_STRING))
     return FALSE;
   
@@ -4971,7 +5053,11 @@ decode_header_data (const DBusString   *data,
           fields[field].name_offset  = pos;
           fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
 
-          _dbus_verbose ("Found reply serial at offset %d\n",
+          _dbus_verbose ("Found reply serial %u at offset %d\n",
+                         _dbus_demarshal_uint32 (data,
+                                                 byte_order,
+                                                 fields[field].value_offset,
+                                                 NULL),
                          fields[field].value_offset);
          break;
 
@@ -6751,6 +6837,8 @@ _dbus_message_test (const char *test_data_dir)
   const unsigned char our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE };
   char sig[64];
   const char *s;
+  char *t;
+  DBusError error;
   
   _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
 
@@ -6952,7 +7040,7 @@ _dbus_message_test (const char *test_data_dir)
 
   _dbus_assert (strcmp (name1, name2) == 0);
   
-  dbus_message_unref (message);
+  dbus_message_unref (message);  
   dbus_message_unref (copy);
 
   message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
@@ -6999,7 +7087,7 @@ _dbus_message_test (const char *test_data_dir)
                                  "data", 5);
   
   message_iter_test (message);
-
+  
   /* Message loader test */
   _dbus_message_lock (message);
   loader = _dbus_message_loader_new ();
@@ -7030,6 +7118,7 @@ _dbus_message_test (const char *test_data_dir)
       _dbus_message_loader_return_buffer (loader, buffer, 1);
     }
 
+  copy = dbus_message_copy (message); /* save for tests below */
   dbus_message_unref (message);
 
   /* Now pop back the message */
@@ -7051,6 +7140,31 @@ _dbus_message_test (const char *test_data_dir)
   dbus_message_unref (message);
   _dbus_message_loader_unref (loader);
 
+  message = dbus_message_new_method_return (copy);
+  if (message == NULL)
+    _dbus_assert_not_reached ("out of memory\n");
+  dbus_message_unref (copy);
+
+  if (!dbus_message_append_args (message,
+                                 DBUS_TYPE_STRING, "hello",
+                                 DBUS_TYPE_INVALID))
+    _dbus_assert_not_reached ("no memory");
+
+  if (!dbus_message_has_signature (message, "s"))
+    _dbus_assert_not_reached ("method return has wrong signature");
+
+  dbus_error_init (&error);
+  if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING,
+                              &t, DBUS_TYPE_INVALID))
+    
+    {
+      _dbus_warn ("Failed to get expected string arg: %s\n", error.message);
+      exit (1);
+    }
+  dbus_free (t);
+  
+  dbus_message_unref (message);
+  
   /* Now load every message in test_data_dir if we have one */
   if (test_data_dir == NULL)
     return TRUE;
index 235bec6..24955bf 100644 (file)
@@ -146,28 +146,28 @@ dbus_bool_t dbus_message_iter_get_args_valist (DBusMessageIter *iter,
                                               va_list          var_args);
 
 
-
-void          dbus_message_iter_init           (DBusMessage      *message,
-                                               DBusMessageIter  *iter);
-dbus_bool_t   dbus_message_iter_has_next       (DBusMessageIter  *iter);
-dbus_bool_t   dbus_message_iter_next           (DBusMessageIter  *iter);
-int           dbus_message_iter_get_arg_type   (DBusMessageIter  *iter);
-int           dbus_message_iter_get_array_type (DBusMessageIter  *iter);
-unsigned char dbus_message_iter_get_byte       (DBusMessageIter  *iter);
-dbus_bool_t   dbus_message_iter_get_boolean    (DBusMessageIter  *iter);
-dbus_int32_t  dbus_message_iter_get_int32      (DBusMessageIter  *iter);
-dbus_uint32_t dbus_message_iter_get_uint32     (DBusMessageIter  *iter);
+void                   dbus_message_iter_init            (DBusMessage      *message,
+                                                          DBusMessageIter  *iter);
+dbus_bool_t            dbus_message_iter_has_next        (DBusMessageIter  *iter);
+dbus_bool_t            dbus_message_iter_next            (DBusMessageIter  *iter);
+int                    dbus_message_iter_get_arg_type    (DBusMessageIter  *iter);
+int                    dbus_message_iter_get_array_type  (DBusMessageIter  *iter);
+unsigned char          dbus_message_iter_get_byte        (DBusMessageIter  *iter);
+dbus_bool_t            dbus_message_iter_get_boolean     (DBusMessageIter  *iter);
+dbus_int32_t           dbus_message_iter_get_int32       (DBusMessageIter  *iter);
+dbus_uint32_t          dbus_message_iter_get_uint32      (DBusMessageIter  *iter);
 #ifdef DBUS_HAVE_INT64
-dbus_int64_t  dbus_message_iter_get_int64      (DBusMessageIter  *iter);
-dbus_uint64_t dbus_message_iter_get_uint64     (DBusMessageIter  *iter);
+dbus_int64_t           dbus_message_iter_get_int64       (DBusMessageIter  *iter);
+dbus_uint64_t          dbus_message_iter_get_uint64      (DBusMessageIter  *iter);
 #endif /* DBUS_HAVE_INT64 */
-double        dbus_message_iter_get_double     (DBusMessageIter  *iter);
-char *        dbus_message_iter_get_string     (DBusMessageIter  *iter);
-char *        dbus_message_iter_get_dict_key   (DBusMessageIter  *iter);
-dbus_bool_t   dbus_message_iter_get_named      (DBusMessageIter  *iter,
-                                               char            **name,
-                                               unsigned char   **value,
-                                               int              *len);
+double                 dbus_message_iter_get_double      (DBusMessageIter  *iter);
+char *                 dbus_message_iter_get_string      (DBusMessageIter  *iter);
+char *                 dbus_message_iter_get_object_path (DBusMessageIter  *iter);
+char *                 dbus_message_iter_get_dict_key    (DBusMessageIter  *iter);
+dbus_bool_t            dbus_message_iter_get_named       (DBusMessageIter  *iter,
+                                                          char            **name,
+                                                          unsigned char   **value,
+                                                          int              *len);
 
 void        dbus_message_iter_init_array_iterator (DBusMessageIter   *iter,
                                                   DBusMessageIter   *array_iter,
@@ -200,6 +200,9 @@ dbus_bool_t dbus_message_iter_get_double_array    (DBusMessageIter   *iter,
 dbus_bool_t dbus_message_iter_get_string_array    (DBusMessageIter   *iter,
                                                   char            ***value,
                                                   int               *len);
+dbus_bool_t dbus_message_iter_get_object_path_array (DBusMessageIter   *iter,
+                                                     char            ***value,
+                                                     int               *len);
 
 
 void        dbus_message_append_iter_init          (DBusMessage          *message,
index e0d8e3e..590f129 100644 (file)
@@ -293,14 +293,16 @@ dbus_pending_call_block (DBusPendingCall *pending)
 
   if (dbus_pending_call_get_completed (pending))
     return;
-  
+
+  /* message may be NULL if no reply */
   message = _dbus_connection_block_for_reply (pending->connection,
                                               pending->reply_serial,
                                               dbus_timeout_get_interval (pending->timeout));
 
   _dbus_connection_lock (pending->connection);
   _dbus_pending_call_complete_and_unlock (pending, message);
-  dbus_message_unref (message);
+  if (message)
+    dbus_message_unref (message);
 }
 
 static DBusDataSlotAllocator slot_allocator;
index 5011f22..8e2a907 100644 (file)
 void
 _dbus_abort (void)
 {
+#ifdef DBUS_ENABLE_VERBOSE_MODE
+  const char *s;
+  s = _dbus_getenv ("DBUS_PRINT_BACKTRACE");
+  if (s && *s)
+    _dbus_print_backtrace ();
+#endif
   abort ();
   _exit (1); /* in case someone manages to ignore SIGABRT */
 }
@@ -3109,7 +3115,11 @@ _dbus_become_daemon (const DBusString *pidfile,
 {
   const char *s;
   pid_t child_pid;
+  int dev_null_fd;
+
+  _dbus_verbose ("Becoming a daemon...\n");
 
+  _dbus_verbose ("chdir to /\n");
   if (chdir ("/") < 0)
     {
       dbus_set_error (error, DBUS_ERROR_FAILED,
@@ -3117,59 +3127,61 @@ _dbus_become_daemon (const DBusString *pidfile,
       return FALSE;
     }
 
+  _dbus_verbose ("forking...\n");
   switch ((child_pid = fork ()))
     {
     case -1:
+      _dbus_verbose ("fork failed\n");
       dbus_set_error (error, _dbus_error_from_errno (errno),
                       "Failed to fork daemon: %s", _dbus_strerror (errno));
       return FALSE;
       break;
 
     case 0:
+      _dbus_verbose ("in child, closing std file descriptors\n");
 
-
-      s = _dbus_getenv ("DBUS_DEBUG_DAEMONIZE");
-      if (s != NULL)
-             kill (_dbus_getpid (), SIGSTOP);
+      /* silently ignore failures here, if someone
+       * doesn't have /dev/null we may as well try
+       * to continue anyhow
+       */
       
-      s = _dbus_getenv ("DBUS_DEBUG_OUTPUT");
-      if (s == NULL || *s == '\0')
+      dev_null_fd = open ("/dev/null", O_RDWR);
+      if (dev_null_fd >= 0)
         {
-          int dev_null_fd;
-
-          /* silently ignore failures here, if someone
-           * doesn't have /dev/null we may as well try
-           * to continue anyhow
-           */
-
-          dev_null_fd = open ("/dev/null", O_RDWR);
-          if (dev_null_fd >= 0)
-            {
-              dup2 (dev_null_fd, 0);
-              dup2 (dev_null_fd, 1);
-              dup2 (dev_null_fd, 2);
-            }
+          dup2 (dev_null_fd, 0);
+          dup2 (dev_null_fd, 1);
+          
+          s = _dbus_getenv ("DBUS_DEBUG_OUTPUT");
+          if (s == NULL || *s == '\0')
+            dup2 (dev_null_fd, 2);
+          else
+            _dbus_verbose ("keeping stderr open due to DBUS_DEBUG_OUTPUT\n");
         }
 
       /* Get a predictable umask */
+      _dbus_verbose ("setting umask\n");
       umask (022);
       break;
 
     default:
       if (pidfile)
         {
+          _dbus_verbose ("parent writing pid file\n");
           if (!_dbus_write_pid_file (pidfile,
                                      child_pid,
                                      error))
             {
+              _dbus_verbose ("pid file write failed, killing child\n");
               kill (child_pid, SIGTERM);
               return FALSE;
             }
         }
+      _dbus_verbose ("parent exiting\n");
       _exit (0);
       break;
     }
 
+  _dbus_verbose ("calling setsid()\n");
   if (setsid () == -1)
     _dbus_assert_not_reached ("setsid() failed");
   
index 6257b09..98d70b0 100644 (file)
--- a/doc/TODO
+++ b/doc/TODO
    we need to have a test for it in the test suite.
 
  - the max_replies_per_connection resource limit isn't implemented
+
+ - array lengths should probably be returned as size_t rather than int
+   (though they are kind of a pita to pass in as size_t with the 
+    varargs, so maybe not - what does glib do with g_object_get()?)
+
+ - the varargs dbus_message_get_args() needs to support OBJECT_PATH 
+   and OBJECT_PATH_ARRAY
index f5e5918..90f00b2 100644 (file)
@@ -380,7 +380,7 @@ gproxy_get_match_rule (DBusGProxy *proxy)
   /* FIXME Some sort of escaping is required here I think */
   
   if (proxy->service)
-    return g_strdup_printf ("type='signal',service='%s',path='%s',interface='%s'",
+    return g_strdup_printf ("type='signal',sender='%s',path='%s',interface='%s'",
                             proxy->service, proxy->path, proxy->interface);
   else
     return g_strdup_printf ("type='signal',path='%s',interface='%s'",
@@ -1068,15 +1068,29 @@ dbus_gproxy_end_call (DBusGProxy          *proxy,
   g_assert (message != NULL);
 
   dbus_error_init (&derror);
-  va_start (args, first_arg_type);
-  if (!dbus_message_get_args_valist (message, &derror, first_arg_type, args))
+
+  switch (dbus_message_get_type (message))
     {
+    case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+      va_start (args, first_arg_type);
+      if (!dbus_message_get_args_valist (message, &derror, first_arg_type, args))
+        {
+          va_end (args);
+          goto error;
+        }
       va_end (args);
+
+      return TRUE;
+      
+    case DBUS_MESSAGE_TYPE_ERROR:
+      dbus_set_error_from_message (&derror, message);
       goto error;
-    }
-  va_end (args);
 
-  return TRUE;
+    default:
+      dbus_set_error (&derror, DBUS_ERROR_FAILED,
+                      "Reply was neither a method return nor an exception");
+      goto error;
+    }
 
  error:
   dbus_set_g_error (error, &derror);
index ccbb9a4..a51396b 100755 (executable)
@@ -4,6 +4,9 @@ SCRIPTNAME=$0
 
 function die() 
 {
+    if ! test -z "$DBUS_SESSION_BUS_PID" ; then
+        kill -9 $DBUS_SESSION_BUS_PID
+    fi
     echo $SCRIPTNAME: $* >&2
     exit 1
 }
@@ -13,11 +16,14 @@ if test -z "$DBUS_TOP_BUILDDIR" ; then
 fi
 
 CONFIG_FILE=./run-test.conf
+SERVICE_DIR="$DBUS_TOP_BUILDDIR/test/data/valid-service-files"
+ESCAPED_SERVICE_DIR=`echo $SERVICE_DIR | sed -e 's/\//\\\\\\//g'`
+echo "escaped service dir is: $ESCAPED_SERVICE_DIR"
 
 ## create a configuration file based on the standard session.conf
 cat $DBUS_TOP_BUILDDIR/bus/session.conf |  \
-  sed -e 's/<servicedir>.*$//g'         |  \
-  sed -e 's/<include.*$//g'                \
+    sed -e 's/<servicedir>.*$/<servicedir>'$ESCAPED_SERVICE_DIR'<\/servicedir>/g' |  \
+    sed -e 's/<include.*$//g'                \
   > $CONFIG_FILE
 
 echo "Created configuration file $CONFIG_FILE"
index c302b23..fb8be4c 100644 (file)
@@ -11,11 +11,14 @@ main (int argc, char **argv)
   GMainLoop *loop;
   GError *error;
   DBusGProxy *driver;
+  DBusGProxy *proxy;
   DBusPendingCall *call;
   char **service_list;
   int service_list_len;
   int i;
-
+  dbus_uint32_t result;
+  char *str;
+  
   g_type_init ();
   
   loop = g_main_loop_new (NULL, FALSE);
@@ -66,7 +69,96 @@ main (int argc, char **argv)
   
   dbus_free_string_array (service_list);
 
+  /* Test handling of unknown method */
+  call = dbus_gproxy_begin_call (driver, "ThisMethodDoesNotExist",
+                                 DBUS_TYPE_STRING,
+                                 "blah blah blah blah blah",
+                                 DBUS_TYPE_INT32,
+                                 10,
+                                 DBUS_TYPE_INVALID);
+
+  error = NULL;
+  if (dbus_gproxy_end_call (driver, call, &error,
+                            DBUS_TYPE_INVALID))
+    {
+      g_printerr ("Calling nonexistent method succeeded!\n");
+      exit (1);
+    }
+
+  g_print ("Got EXPECTED error from calling unknown method: %s\n",
+           error->message);
+  g_error_free (error);
+  
+  /* Activate a service */
+  call = dbus_gproxy_begin_call (driver, "ActivateService",
+                                 DBUS_TYPE_STRING,
+                                 "org.freedesktop.DBus.TestSuiteEchoService",
+                                 DBUS_TYPE_UINT32,
+                                 0,
+                                 DBUS_TYPE_INVALID);
+
+  error = NULL;
+  if (!dbus_gproxy_end_call (driver, call, &error,
+                             DBUS_TYPE_UINT32, &result,
+                             DBUS_TYPE_INVALID))
+    {
+      g_printerr ("Failed to complete Activate call: %s\n",
+                  error->message);
+      g_error_free (error);
+      exit (1);
+    }
+
+  g_print ("Activation of echo service = 0x%x\n", result);
+
+  /* Activate a service again */
+  call = dbus_gproxy_begin_call (driver, "ActivateService",
+                                 DBUS_TYPE_STRING,
+                                 "org.freedesktop.DBus.TestSuiteEchoService",
+                                 DBUS_TYPE_UINT32,
+                                 0,
+                                 DBUS_TYPE_INVALID);
+
+  error = NULL;
+  if (!dbus_gproxy_end_call (driver, call, &error,
+                             DBUS_TYPE_UINT32, &result,
+                             DBUS_TYPE_INVALID))
+    {
+      g_printerr ("Failed to complete Activate call: %s\n",
+                  error->message);
+      g_error_free (error);
+      exit (1);
+    }
+
+  g_print ("Duplicate activation of echo service = 0x%x\n", result);
+
+  /* Talk to the new service */
+  
+  proxy = dbus_gproxy_new_for_service (connection,
+                                       "org.freedesktop.DBus.TestSuiteEchoService",
+                                       "/fixme/the/test/service/ignores/this", /* FIXME */
+                                       "org.freedesktop.TestSuite");
+  
+  call = dbus_gproxy_begin_call (proxy, "Echo",
+                                 DBUS_TYPE_STRING,
+                                 "my string hello",
+                                 DBUS_TYPE_INVALID);
+
+  error = NULL;
+  if (!dbus_gproxy_end_call (proxy, call, &error,
+                             DBUS_TYPE_STRING, &str,
+                             DBUS_TYPE_INVALID))
+    {
+      g_printerr ("Failed to complete Echo call: %s\n",
+                  error->message);
+      g_error_free (error);
+      exit (1);
+    }
+
+  g_print ("String echoed = \"%s\"\n", str);
+  dbus_free (str);
+  
   g_object_unref (G_OBJECT (driver));
+  g_object_unref (G_OBJECT (proxy));
   
   g_print ("Successfully completed %s\n", argv[0]);
   
index d07575e..c72a43a 100644 (file)
@@ -27,7 +27,6 @@ handle_echo (DBusConnection     *connection,
 {
   DBusError error;
   DBusMessage *reply;
-  DBusMessageIter iter;
   char *s;
   
   dbus_error_init (&error);
@@ -55,20 +54,22 @@ handle_echo (DBusConnection     *connection,
   reply = dbus_message_new_method_return (message);
   if (reply == NULL)
     die ("No memory\n");
-
-  dbus_message_append_iter_init (message, &iter);
   
-  if (!dbus_message_iter_append_string (&iter, s))
+  if (!dbus_message_append_args (reply,
+                                 DBUS_TYPE_STRING, s,
+                                 DBUS_TYPE_INVALID))
     die ("No memory");
-
+  
   if (!dbus_connection_send (connection, reply, NULL))
     die ("No memory\n");
+
+  fprintf (stderr, "Echo service echoed string: \"%s\"\n", s);
   
   dbus_free (s);
   
   dbus_message_unref (reply);
     
-  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+  return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 static DBusHandlerResult
index dc9dad4..e07141a 100644 (file)
@@ -239,7 +239,8 @@ do_write (int fd, const void *buf, size_t count)
         goto again;
       else
         {
-          fprintf (stderr, "Failed to write data to pipe!\n");
+          fprintf (stderr, "Failed to write data to pipe! %s\n",
+                   strerror (errno));
           exit (1); /* give up, we suck */
         }
     }
@@ -461,6 +462,10 @@ babysit (int   exit_with_session,
   long val;
   char *end;
   int dev_null_fd;
+  const char *s;
+
+  verbose ("babysitting, exit_with_session = %d, child_pid = %ld, read_bus_pid_fd = %d, write_bus_pid_fd = %d\n",
+           exit_with_session, (long) child_pid, read_bus_pid_fd, write_bus_pid_fd);
   
   /* We chdir ("/") since we are persistent and daemon-like, and fork
    * again so dbus-launch can reap the parent.  However, we don't
@@ -476,14 +481,19 @@ babysit (int   exit_with_session,
       exit (1);
     }
 
-  /* Move stdout/stderr so we don't block an "eval" or otherwise
-   * lock up.
+  /* Close stdout/stderr so we don't block an "eval" or otherwise
+   * lock up. stdout is still chaining through to dbus-launch
+   * and in turn to the parent shell.
    */
   dev_null_fd = open ("/dev/null", O_RDWR);
   if (dev_null_fd >= 0)
     {
+      if (!exit_with_session)
+        dup2 (dev_null_fd, 0);
       dup2 (dev_null_fd, 1);
-      dup2 (dev_null_fd, 2);
+      s = getenv ("DBUS_DEBUG_OUTPUT");
+      if (s == NULL || *s == '\0')
+        dup2 (dev_null_fd, 2);
     }
   else
     {
@@ -888,6 +898,11 @@ main (int argc, char **argv)
        }
          
       verbose ("dbus-launch exiting\n");
+
+      fflush (stdout);
+      fflush (stderr);
+      close (1);
+      close (2);
       
       exit (0);
     }