+static dbus_bool_t
+check_send_exit_to_service (BusContext *context,
+ DBusConnection *connection,
+ const char *service_name,
+ const char *base_service)
+{
+ dbus_bool_t got_error;
+ DBusMessage *message;
+ dbus_int32_t serial;
+ dbus_bool_t retval;
+
+ _dbus_verbose ("Sending exit message to the test service\n");
+
+ retval = FALSE;
+
+ /* Kill off the test service by sending it a quit message */
+ message = dbus_message_new (service_name,
+ "org.freedesktop.DBus.TestSuiteExit");
+
+ if (message == NULL)
+ {
+ /* Do this again; we still need the service to exit... */
+ if (!check_send_exit_to_service (context, connection,
+ service_name, base_service))
+ goto out;
+
+ return TRUE;
+ }
+
+ if (!dbus_connection_send (connection, message, &serial))
+ {
+ dbus_message_unref (message);
+
+ /* Do this again; we still need the service to exit... */
+ if (!check_send_exit_to_service (context, connection,
+ service_name, base_service))
+ goto out;
+
+ return TRUE;
+ }
+
+ dbus_message_unref (message);
+ message = NULL;
+
+ /* send message */
+ bus_test_run_clients_loop (TRUE);
+
+ /* read it in and write it out to test service */
+ bus_test_run_bus_loop (context, FALSE);
+
+ /* see if we got an error during message bus dispatching */
+ bus_test_run_clients_loop (FALSE);
+ message = dbus_connection_borrow_message (connection);
+ got_error = message != NULL && dbus_message_get_is_error (message);
+ if (message)
+ dbus_connection_return_message (connection, message);
+
+ if (!got_error)
+ {
+ /* If no error, wait for the test service to exit */
+ block_connection_until_message_from_bus (context, connection);
+
+ bus_test_run_everything (context);
+ }
+
+ if (got_error)
+ {
+ message = pop_message_waiting_for_memory (connection);
+ _dbus_assert (message != NULL);
+
+ if (!dbus_message_get_is_error (message))
+ {
+ _dbus_warn ("expecting an error reply to asking test service to exit, got %s\n",
+ dbus_message_get_name (message));
+ goto out;
+ }
+ else if (!dbus_message_name_is (message, DBUS_ERROR_NO_MEMORY))
+ {
+ _dbus_warn ("not expecting error %s when asking test service to exit\n",
+ dbus_message_get_name (message));
+ goto out;
+ }
+
+ _dbus_verbose ("Got error %s when asking test service to exit\n",
+ dbus_message_get_name (message));
+
+ /* Do this again; we still need the service to exit... */
+ if (!check_send_exit_to_service (context, connection,
+ service_name, base_service))
+ goto out;
+ }
+ else
+ {
+ if (!check_service_deactivated (context, connection,
+ service_name, base_service))
+ goto out;
+ }
+
+ retval = TRUE;
+
+ out:
+ if (message)
+ dbus_message_unref (message);
+
+ return retval;
+}
+
+static dbus_bool_t
+check_got_error (BusContext *context,
+ DBusConnection *connection,
+ const char *error_name)
+{
+ DBusMessage *message;
+ dbus_bool_t retval;
+
+ retval = FALSE;
+
+ message = pop_message_waiting_for_memory (connection);
+ if (message == NULL)
+ {
+ _dbus_warn ("Did not get an expected error\n");
+ goto out;
+ }
+
+ if (!dbus_message_get_is_error (message))
+ {
+ _dbus_warn ("Expected an error, got %s\n",
+ dbus_message_get_name (message));
+ goto out;
+ }
+
+ if (!dbus_message_name_is (message, error_name))
+ {
+ _dbus_warn ("Expected error %s, got %s instead\n",
+ error_name,
+ dbus_message_get_name (message));
+ goto out;
+ }
+
+ retval = TRUE;
+
+ out:
+ if (message)
+ dbus_message_unref (message);
+
+ return retval;
+}
+