diff options
author | Havoc Pennington <hp@redhat.com> | 2003-10-16 06:34:51 +0000 |
---|---|---|
committer | Havoc Pennington <hp@redhat.com> | 2003-10-16 06:34:51 +0000 |
commit | d6e1b2adb3d8e51ce1bb47295cef12d9fe1a15a8 (patch) | |
tree | d94b220a2886b384ddc4f55df4689d79430a6399 | |
parent | 9b9dd4b80eb2753fc67bed1f48eef89674ba968e (diff) |
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.
-rw-r--r-- | ChangeLog | 54 | ||||
-rw-r--r-- | bus/activation.c | 15 | ||||
-rw-r--r-- | bus/bus.c | 6 | ||||
-rw-r--r-- | bus/connection.c | 109 | ||||
-rw-r--r-- | bus/signals.c | 36 | ||||
-rw-r--r-- | bus/system.conf.in | 2 | ||||
-rw-r--r-- | dbus/dbus-bus.c | 27 | ||||
-rw-r--r-- | dbus/dbus-connection.c | 43 | ||||
-rw-r--r-- | dbus/dbus-internals.c | 8 | ||||
-rw-r--r-- | dbus/dbus-internals.h | 20 | ||||
-rw-r--r-- | dbus/dbus-message.c | 126 | ||||
-rw-r--r-- | dbus/dbus-message.h | 43 | ||||
-rw-r--r-- | dbus/dbus-pending-call.c | 6 | ||||
-rw-r--r-- | dbus/dbus-sysdeps.c | 52 | ||||
-rw-r--r-- | doc/TODO | 7 | ||||
-rw-r--r-- | glib/dbus-gproxy.c | 26 | ||||
-rwxr-xr-x | test/glib/run-test.sh | 10 | ||||
-rw-r--r-- | test/glib/test-dbus-glib.c | 94 | ||||
-rw-r--r-- | test/test-service.c | 13 | ||||
-rw-r--r-- | tools/dbus-launch.c | 23 |
20 files changed, 597 insertions, 123 deletions
@@ -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 diff --git a/bus/activation.c b/bus/activation.c index 91d3c116..5588ed86 100644 --- a/bus/activation.c +++ b/bus/activation.c @@ -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); + } } } @@ -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 diff --git a/bus/connection.c b/bus/connection.c index 1e562427..65ebdb28 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -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; diff --git a/bus/signals.c b/bus/signals.c index 0fd4b514..9c0d31e2 100644 --- a/bus/signals.c +++ b/bus/signals.c @@ -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) diff --git a/bus/system.conf.in b/bus/system.conf.in index 8e2dbda9..167ac39f 100644 --- a/bus/system.conf.in +++ b/bus/system.conf.in @@ -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 diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c index 0c9f58e1..58df18d3 100644 --- a/dbus/dbus-bus.c +++ b/dbus/dbus-bus.c @@ -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) diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index ed7d57d0..bceef2a6 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -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, diff --git a/dbus/dbus-internals.c b/dbus/dbus-internals.c index 44f3ff47..9a2aa2b1 100644 --- a/dbus/dbus-internals.c +++ b/dbus/dbus-internals.c @@ -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 (); } } diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h index fa1ad19c..0284da0e 100644 --- a/dbus/dbus-internals.h +++ b/dbus/dbus-internals.h @@ -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 */ diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index c7e0b8cf..4c21946a 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -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; diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h index 235bec6d..24955bfa 100644 --- a/dbus/dbus-message.h +++ b/dbus/dbus-message.h @@ -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, diff --git a/dbus/dbus-pending-call.c b/dbus/dbus-pending-call.c index e0d8e3ee..590f1296 100644 --- a/dbus/dbus-pending-call.c +++ b/dbus/dbus-pending-call.c @@ -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; diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index 5011f224..8e2a9071 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -76,6 +76,12 @@ 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"); @@ -117,3 +117,10 @@ 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 diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index f5e59186..90f00b25 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -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); diff --git a/test/glib/run-test.sh b/test/glib/run-test.sh index ccbb9a4a..a51396bb 100755 --- a/test/glib/run-test.sh +++ b/test/glib/run-test.sh @@ -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" diff --git a/test/glib/test-dbus-glib.c b/test/glib/test-dbus-glib.c index c302b239..fb8be4cc 100644 --- a/test/glib/test-dbus-glib.c +++ b/test/glib/test-dbus-glib.c @@ -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]); diff --git a/test/test-service.c b/test/test-service.c index d07575e2..c72a43af 100644 --- a/test/test-service.c +++ b/test/test-service.c @@ -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 diff --git a/tools/dbus-launch.c b/tools/dbus-launch.c index dc9dad45..e07141a1 100644 --- a/tools/dbus-launch.c +++ b/tools/dbus-launch.c @@ -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); } |