1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dispatch.c Message dispatcher
4 * Copyright (C) 2003 CodeFactory AB
5 * Copyright (C) 2003 Red Hat, Inc.
7 * Licensed under the Academic Free License version 1.2
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "connection.h"
33 #include <dbus/dbus-internals.h>
37 send_one_message (DBusConnection *connection,
39 DBusConnection *sender,
40 DBusConnection *addressed_recipient,
42 BusTransaction *transaction,
45 if (!bus_context_check_security_policy (context, transaction,
51 return TRUE; /* silently don't send it */
53 if (!bus_transaction_send (transaction,
65 bus_dispatch_matches (BusTransaction *transaction,
66 DBusConnection *sender,
67 DBusConnection *addressed_recipient,
72 BusConnections *connections;
74 BusMatchmaker *matchmaker;
78 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
80 /* sender and recipient can both be NULL for the bus driver,
81 * or for signals with no particular recipient
84 _dbus_assert (sender == NULL || bus_connection_is_active (sender));
85 _dbus_assert (dbus_message_get_sender (message) != NULL);
87 connections = bus_transaction_get_connections (transaction);
89 dbus_error_init (&tmp_error);
90 context = bus_transaction_get_context (transaction);
91 matchmaker = bus_context_get_matchmaker (context);
94 if (!bus_matchmaker_get_recipients (matchmaker,
95 bus_context_get_connections (context),
96 sender, addressed_recipient, message,
103 link = _dbus_list_get_first_link (&recipients);
106 DBusConnection *dest;
110 if (!send_one_message (dest, context, sender, addressed_recipient,
111 message, transaction, &tmp_error))
114 link = _dbus_list_get_next_link (&recipients, link);
117 _dbus_list_clear (&recipients);
119 if (dbus_error_is_set (&tmp_error))
121 dbus_move_error (&tmp_error, error);
128 static DBusHandlerResult
129 bus_dispatch (DBusConnection *connection,
130 DBusMessage *message)
132 const char *sender, *service_name;
134 BusTransaction *transaction;
136 DBusHandlerResult result;
137 DBusConnection *addressed_recipient;
139 result = DBUS_HANDLER_RESULT_HANDLED;
142 addressed_recipient = NULL;
143 dbus_error_init (&error);
145 context = bus_connection_get_context (connection);
146 _dbus_assert (context != NULL);
148 /* If we can't even allocate an OOM error, we just go to sleep
151 while (!bus_connection_preallocate_oom_error (connection))
152 _dbus_wait_for_memory ();
154 /* Ref connection in case we disconnect it at some point in here */
155 dbus_connection_ref (connection);
157 service_name = dbus_message_get_destination (message);
159 #ifdef DBUS_ENABLE_VERBOSE_MODE
161 const char *interface_name, *member_name, *error_name;
163 interface_name = dbus_message_get_interface (message);
164 member_name = dbus_message_get_member (message);
165 error_name = dbus_message_get_error_name (message);
167 _dbus_verbose ("DISPATCH: %s %s %s to %s\n",
168 interface_name ? interface_name : "(no interface)",
169 member_name ? member_name : "(no member)",
170 error_name ? error_name : "(no error name)",
171 service_name ? service_name : "peer");
173 #endif /* DBUS_ENABLE_VERBOSE_MODE */
175 /* If service_name is NULL, if it's a signal we send it to all
176 * connections with a match rule. If it's not a signal, there
177 * are some special cases here but mostly we just bail out.
179 if (service_name == NULL)
181 if (dbus_message_is_signal (message,
182 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
185 bus_connection_disconnected (connection);
189 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL)
191 /* DBusConnection also handles some of these automatically, we leave
194 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
199 /* Create our transaction */
200 transaction = bus_transaction_new (context);
201 if (transaction == NULL)
203 BUS_SET_OOM (&error);
207 /* Assign a sender to the message */
208 if (bus_connection_is_active (connection))
210 sender = bus_connection_get_name (connection);
211 _dbus_assert (sender != NULL);
213 if (!dbus_message_set_sender (message, sender))
215 BUS_SET_OOM (&error);
219 /* We need to refetch the service name here, because
220 * dbus_message_set_sender can cause the header to be
221 * reallocated, and thus the service_name pointer will become
224 service_name = dbus_message_get_destination (message);
228 strcmp (service_name, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS) == 0) /* to bus driver */
230 if (!bus_context_check_security_policy (context, transaction,
231 connection, NULL, NULL, message, &error))
233 _dbus_verbose ("Security policy rejected message\n");
237 _dbus_verbose ("Giving message to %s\n", DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
238 if (!bus_driver_handle_message (connection, transaction, message, &error))
241 else if (!bus_connection_is_active (connection)) /* clients must talk to bus driver first */
243 _dbus_verbose ("Received message from non-registered client. Disconnecting.\n");
244 dbus_connection_disconnect (connection);
247 else if (service_name != NULL) /* route to named service */
249 DBusString service_string;
251 BusRegistry *registry;
253 _dbus_assert (service_name != NULL);
255 registry = bus_connection_get_registry (connection);
257 _dbus_string_init_const (&service_string, service_name);
258 service = bus_registry_lookup (registry, &service_string);
262 dbus_set_error (&error,
263 DBUS_ERROR_SERVICE_DOES_NOT_EXIST,
264 "Service \"%s\" does not exist",
270 addressed_recipient = bus_service_get_primary_owner (service);
271 _dbus_assert (addressed_recipient != NULL);
273 if (!bus_context_check_security_policy (context, transaction,
274 connection, addressed_recipient,
279 /* Dispatch the message */
280 if (!bus_transaction_send (transaction, addressed_recipient, message))
282 BUS_SET_OOM (&error);
288 /* Now match the messages against any match rules, which will send
289 * out signals and such. addressed_recipient may == NULL.
291 if (!bus_dispatch_matches (transaction, connection, addressed_recipient, message, &error))
295 if (dbus_error_is_set (&error))
297 if (!dbus_connection_get_is_connected (connection))
299 /* If we disconnected it, we won't bother to send it any error
302 _dbus_verbose ("Not sending error to connection we disconnected\n");
304 else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
306 bus_connection_send_oom_error (connection, message);
308 /* cancel transaction due to OOM */
309 if (transaction != NULL)
311 bus_transaction_cancel_and_free (transaction);
317 /* Try to send the real error, if no mem to do that, send
320 _dbus_assert (transaction != NULL);
322 if (!bus_transaction_send_error_reply (transaction, connection,
325 bus_connection_send_oom_error (connection, message);
327 /* cancel transaction due to OOM */
328 if (transaction != NULL)
330 bus_transaction_cancel_and_free (transaction);
336 dbus_error_free (&error);
339 if (transaction != NULL)
341 bus_transaction_execute_and_free (transaction);
344 dbus_connection_unref (connection);
349 static DBusHandlerResult
350 bus_dispatch_message_filter (DBusConnection *connection,
351 DBusMessage *message,
354 return bus_dispatch (connection, message);
358 bus_dispatch_add_connection (DBusConnection *connection)
360 if (!dbus_connection_add_filter (connection,
361 bus_dispatch_message_filter,
369 bus_dispatch_remove_connection (DBusConnection *connection)
371 /* Here we tell the bus driver that we want to get off. */
372 bus_driver_remove_connection (connection);
374 dbus_connection_remove_filter (connection,
375 bus_dispatch_message_filter,
379 #ifdef DBUS_BUILD_TESTS
381 typedef dbus_bool_t (* Check1Func) (BusContext *context);
382 typedef dbus_bool_t (* Check2Func) (BusContext *context,
383 DBusConnection *connection);
385 static dbus_bool_t check_no_leftovers (BusContext *context);
388 block_connection_until_message_from_bus (BusContext *context,
389 DBusConnection *connection)
391 while (dbus_connection_get_dispatch_status (connection) ==
392 DBUS_DISPATCH_COMPLETE &&
393 dbus_connection_get_is_connected (connection))
395 bus_test_run_bus_loop (context, TRUE);
396 bus_test_run_clients_loop (FALSE);
400 /* compensate for fact that pop_message() can return #NULL due to OOM */
402 pop_message_waiting_for_memory (DBusConnection *connection)
404 while (dbus_connection_get_dispatch_status (connection) ==
405 DBUS_DISPATCH_NEED_MEMORY)
406 _dbus_wait_for_memory ();
408 return dbus_connection_pop_message (connection);
412 warn_unexpected_real (DBusConnection *connection,
413 DBusMessage *message,
414 const char *expected,
415 const char *function,
419 _dbus_warn ("%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s\n",
421 dbus_message_get_interface (message) ?
422 dbus_message_get_interface (message) : "(unset)",
423 dbus_message_get_member (message) ?
424 dbus_message_get_member (message) : "(unset)",
425 dbus_message_get_error_name (message) ?
426 dbus_message_get_error_name (message) : "(unset)",
430 _dbus_warn ("%s:%d received no message on %p, expecting %s\n",
431 function, line, connection, expected);
434 #define warn_unexpected(connection, message, expected) \
435 warn_unexpected_real (connection, message, expected, _DBUS_FUNCTION_NAME, __LINE__)
438 verbose_message_received (DBusConnection *connection,
439 DBusMessage *message)
441 _dbus_verbose ("Received message interface \"%s\" member \"%s\" error name \"%s\" on %p\n",
442 dbus_message_get_interface (message) ?
443 dbus_message_get_interface (message) : "(unset)",
444 dbus_message_get_member (message) ?
445 dbus_message_get_member (message) : "(unset)",
446 dbus_message_get_error_name (message) ?
447 dbus_message_get_error_name (message) : "(unset)",
453 const char *expected_service_name;
455 } CheckServiceDeletedData;
458 check_service_deleted_foreach (DBusConnection *connection,
461 CheckServiceDeletedData *d = data;
462 DBusMessage *message;
466 dbus_error_init (&error);
470 message = pop_message_waiting_for_memory (connection);
473 _dbus_warn ("Did not receive a message on %p, expecting %s\n",
474 connection, "ServiceDeleted");
477 else if (!dbus_message_is_signal (message,
478 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
481 warn_unexpected (connection, message, "ServiceDeleted");
487 if (!dbus_message_get_args (message, &error,
488 DBUS_TYPE_STRING, &service_name,
491 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
493 _dbus_verbose ("no memory to get service name arg\n");
497 _dbus_assert (dbus_error_is_set (&error));
498 _dbus_warn ("Did not get the expected single string argument\n");
502 else if (strcmp (service_name, d->expected_service_name) != 0)
504 _dbus_warn ("expected deletion of service %s, got deletion of %s\n",
505 d->expected_service_name,
514 dbus_free (service_name);
515 dbus_error_free (&error);
518 dbus_message_unref (message);
524 kill_client_connection (BusContext *context,
525 DBusConnection *connection)
529 CheckServiceDeletedData csdd;
531 _dbus_verbose ("killing connection %p\n", connection);
533 s = dbus_bus_get_base_service (connection);
534 _dbus_assert (s != NULL);
536 while ((base_service = _dbus_strdup (s)) == NULL)
537 _dbus_wait_for_memory ();
539 dbus_connection_ref (connection);
541 /* kick in the disconnect handler that unrefs the connection */
542 dbus_connection_disconnect (connection);
544 bus_test_run_everything (context);
546 _dbus_assert (bus_test_client_listed (connection));
548 /* Run disconnect handler in test.c */
549 if (bus_connection_dispatch_one_message (connection))
550 _dbus_assert_not_reached ("something received on connection being killed other than the disconnect");
552 _dbus_assert (!dbus_connection_get_is_connected (connection));
553 dbus_connection_unref (connection);
555 _dbus_assert (!bus_test_client_listed (connection));
557 csdd.expected_service_name = base_service;
560 bus_test_clients_foreach (check_service_deleted_foreach,
563 dbus_free (base_service);
566 _dbus_assert_not_reached ("didn't get the expected ServiceDeleted messages");
568 if (!check_no_leftovers (context))
569 _dbus_assert_not_reached ("stuff left in message queues after disconnecting a client");
573 kill_client_connection_unchecked (DBusConnection *connection)
575 /* This kills the connection without expecting it to affect
576 * the rest of the bus.
578 _dbus_verbose ("Unchecked kill of connection %p\n", connection);
580 dbus_connection_ref (connection);
581 dbus_connection_disconnect (connection);
582 /* dispatching disconnect handler will unref once */
583 if (bus_connection_dispatch_one_message (connection))
584 _dbus_assert_not_reached ("message other than disconnect dispatched after failure to register");
586 _dbus_assert (!bus_test_client_listed (connection));
587 dbus_connection_unref (connection);
593 } CheckNoMessagesData;
596 check_no_messages_foreach (DBusConnection *connection,
599 CheckNoMessagesData *d = data;
600 DBusMessage *message;
602 message = pop_message_waiting_for_memory (connection);
605 warn_unexpected (connection, message, "no messages");
611 dbus_message_unref (message);
617 DBusConnection *skip_connection;
618 const char *expected_service_name;
620 } CheckServiceCreatedData;
623 check_service_created_foreach (DBusConnection *connection,
626 CheckServiceCreatedData *d = data;
627 DBusMessage *message;
631 if (connection == d->skip_connection)
634 dbus_error_init (&error);
638 message = pop_message_waiting_for_memory (connection);
641 _dbus_warn ("Did not receive a message on %p, expecting %s\n",
642 connection, "ServiceCreated");
645 else if (!dbus_message_is_signal (message,
646 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
649 warn_unexpected (connection, message, "ServiceCreated");
654 if (!dbus_message_get_args (message, &error,
655 DBUS_TYPE_STRING, &service_name,
658 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
660 _dbus_verbose ("no memory to get service name arg\n");
664 _dbus_assert (dbus_error_is_set (&error));
665 _dbus_warn ("Did not get the expected single string argument\n");
669 else if (strcmp (service_name, d->expected_service_name) != 0)
671 _dbus_warn ("expected creation of service %s, got creation of %s\n",
672 d->expected_service_name,
681 dbus_free (service_name);
682 dbus_error_free (&error);
685 dbus_message_unref (message);
691 check_no_leftovers (BusContext *context)
693 CheckNoMessagesData nmd;
696 bus_test_clients_foreach (check_no_messages_foreach,
705 /* returns TRUE if the correct thing happens,
706 * but the correct thing may include OOM errors.
709 check_hello_message (BusContext *context,
710 DBusConnection *connection)
712 DBusMessage *message;
713 dbus_uint32_t serial;
720 dbus_error_init (&error);
725 _dbus_verbose ("check_hello_message for %p\n", connection);
727 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
728 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
729 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
735 if (!dbus_connection_send (connection, message, &serial))
737 dbus_message_unref (message);
741 dbus_message_unref (message);
744 /* send our message */
745 bus_test_run_clients_loop (TRUE);
747 dbus_connection_ref (connection); /* because we may get disconnected */
748 block_connection_until_message_from_bus (context, connection);
750 if (!dbus_connection_get_is_connected (connection))
752 _dbus_verbose ("connection was disconnected\n");
754 dbus_connection_unref (connection);
759 dbus_connection_unref (connection);
761 message = pop_message_waiting_for_memory (connection);
764 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
765 "Hello", serial, connection);
769 verbose_message_received (connection, message);
771 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
773 _dbus_warn ("Message has wrong sender %s\n",
774 dbus_message_get_sender (message) ?
775 dbus_message_get_sender (message) : "(none)");
779 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
781 if (dbus_message_is_error (message,
782 DBUS_ERROR_NO_MEMORY))
784 ; /* good, this is a valid response */
788 warn_unexpected (connection, message, "not this error");
795 CheckServiceCreatedData scd;
797 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
799 ; /* good, expected */
803 warn_unexpected (connection, message, "method return for Hello");
808 retry_get_hello_name:
809 if (!dbus_message_get_args (message, &error,
810 DBUS_TYPE_STRING, &name,
813 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
815 _dbus_verbose ("no memory to get service name arg from hello\n");
816 dbus_error_free (&error);
817 _dbus_wait_for_memory ();
818 goto retry_get_hello_name;
822 _dbus_assert (dbus_error_is_set (&error));
823 _dbus_warn ("Did not get the expected single string argument to hello\n");
828 _dbus_verbose ("Got hello name: %s\n", name);
830 while (!dbus_bus_set_base_service (connection, name))
831 _dbus_wait_for_memory ();
833 scd.skip_connection = connection; /* we haven't done AddMatch so won't get it ourselves */
835 scd.expected_service_name = name;
836 bus_test_clients_foreach (check_service_created_foreach,
842 /* Client should also have gotten ServiceAcquired */
843 dbus_message_unref (message);
844 message = pop_message_waiting_for_memory (connection);
847 _dbus_warn ("Expecting %s, got nothing\n",
852 retry_get_acquired_name:
853 if (!dbus_message_get_args (message, &error,
854 DBUS_TYPE_STRING, &acquired,
857 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
859 _dbus_verbose ("no memory to get service name arg from acquired\n");
860 dbus_error_free (&error);
861 _dbus_wait_for_memory ();
862 goto retry_get_acquired_name;
866 _dbus_assert (dbus_error_is_set (&error));
867 _dbus_warn ("Did not get the expected single string argument to ServiceAcquired\n");
872 _dbus_verbose ("Got acquired name: %s\n", acquired);
874 if (strcmp (acquired, name) != 0)
876 _dbus_warn ("Acquired name is %s but expected %s\n",
882 if (!check_no_leftovers (context))
888 dbus_error_free (&error);
891 dbus_free (acquired);
894 dbus_message_unref (message);
899 /* returns TRUE if the correct thing happens,
900 * but the correct thing may include OOM errors.
903 check_add_match_all (BusContext *context,
904 DBusConnection *connection)
906 DBusMessage *message;
908 dbus_uint32_t serial;
912 dbus_error_init (&error);
915 _dbus_verbose ("check_add_match_all for %p\n", connection);
917 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
918 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
919 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
925 /* empty string match rule matches everything */
926 if (!dbus_message_append_args (message, DBUS_TYPE_STRING, "",
929 dbus_message_unref (message);
933 if (!dbus_connection_send (connection, message, &serial))
935 dbus_message_unref (message);
939 dbus_message_unref (message);
942 /* send our message */
943 bus_test_run_clients_loop (TRUE);
945 dbus_connection_ref (connection); /* because we may get disconnected */
946 block_connection_until_message_from_bus (context, connection);
948 if (!dbus_connection_get_is_connected (connection))
950 _dbus_verbose ("connection was disconnected\n");
952 dbus_connection_unref (connection);
957 dbus_connection_unref (connection);
959 message = pop_message_waiting_for_memory (connection);
962 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
963 "AddMatch", serial, connection);
967 verbose_message_received (connection, message);
969 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
971 _dbus_warn ("Message has wrong sender %s\n",
972 dbus_message_get_sender (message) ?
973 dbus_message_get_sender (message) : "(none)");
977 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
979 if (dbus_message_is_error (message,
980 DBUS_ERROR_NO_MEMORY))
982 ; /* good, this is a valid response */
986 warn_unexpected (connection, message, "not this error");
993 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
995 ; /* good, expected */
996 _dbus_assert (dbus_message_get_reply_serial (message) == serial);
1000 warn_unexpected (connection, message, "method return for AddMatch");
1006 if (!check_no_leftovers (context))
1012 dbus_error_free (&error);
1015 dbus_message_unref (message);
1020 /* returns TRUE if the correct thing happens,
1021 * but the correct thing may include OOM errors.
1024 check_hello_connection (BusContext *context)
1026 DBusConnection *connection;
1029 dbus_error_init (&error);
1031 connection = dbus_connection_open ("debug-pipe:name=test-server", &error);
1032 if (connection == NULL)
1034 _DBUS_ASSERT_ERROR_IS_SET (&error);
1035 dbus_error_free (&error);
1039 if (!bus_setup_debug_client (connection))
1041 dbus_connection_disconnect (connection);
1042 dbus_connection_unref (connection);
1046 if (!check_hello_message (context, connection))
1049 if (dbus_bus_get_base_service (connection) == NULL)
1051 /* We didn't successfully register, so we can't
1052 * do the usual kill_client_connection() checks
1054 kill_client_connection_unchecked (connection);
1058 if (!check_add_match_all (context, connection))
1061 kill_client_connection (context, connection);
1067 #define NONEXISTENT_SERVICE_NAME "test.this.service.does.not.exist.ewuoiurjdfxcvn"
1069 /* returns TRUE if the correct thing happens,
1070 * but the correct thing may include OOM errors.
1073 check_nonexistent_service_activation (BusContext *context,
1074 DBusConnection *connection)
1076 DBusMessage *message;
1077 dbus_uint32_t serial;
1081 dbus_error_init (&error);
1083 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1084 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1085 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1088 if (message == NULL)
1091 if (!dbus_message_append_args (message,
1092 DBUS_TYPE_STRING, NONEXISTENT_SERVICE_NAME,
1093 DBUS_TYPE_UINT32, 0,
1096 dbus_message_unref (message);
1100 if (!dbus_connection_send (connection, message, &serial))
1102 dbus_message_unref (message);
1106 dbus_message_unref (message);
1109 bus_test_run_everything (context);
1110 block_connection_until_message_from_bus (context, connection);
1111 bus_test_run_everything (context);
1113 if (!dbus_connection_get_is_connected (connection))
1115 _dbus_verbose ("connection was disconnected\n");
1121 message = pop_message_waiting_for_memory (connection);
1122 if (message == NULL)
1124 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1125 "ActivateService", serial, connection);
1129 verbose_message_received (connection, message);
1131 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1133 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1135 _dbus_warn ("Message has wrong sender %s\n",
1136 dbus_message_get_sender (message) ?
1137 dbus_message_get_sender (message) : "(none)");
1141 if (dbus_message_is_error (message,
1142 DBUS_ERROR_NO_MEMORY))
1144 ; /* good, this is a valid response */
1146 else if (dbus_message_is_error (message,
1147 DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND))
1149 ; /* good, this is expected also */
1153 warn_unexpected (connection, message, "not this error");
1159 _dbus_warn ("Did not expect to successfully activate %s\n",
1160 NONEXISTENT_SERVICE_NAME);
1168 dbus_message_unref (message);
1174 check_base_service_activated (BusContext *context,
1175 DBusConnection *connection,
1176 DBusMessage *initial_message,
1177 char **base_service_p)
1179 DBusMessage *message;
1184 base_service = NULL;
1187 dbus_error_init (&error);
1189 message = initial_message;
1190 dbus_message_ref (message);
1192 if (dbus_message_is_signal (message,
1193 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1197 CheckServiceCreatedData scd;
1199 reget_service_name_arg:
1200 if (!dbus_message_get_args (message, &error,
1201 DBUS_TYPE_STRING, &service_name,
1204 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1206 dbus_error_free (&error);
1207 _dbus_wait_for_memory ();
1208 goto reget_service_name_arg;
1212 _dbus_warn ("Message %s doesn't have a service name: %s\n",
1215 dbus_error_free (&error);
1220 if (*service_name != ':')
1222 _dbus_warn ("Expected base service activation, got \"%s\" instead\n",
1227 base_service = service_name;
1228 service_name = NULL;
1230 scd.skip_connection = connection;
1232 scd.expected_service_name = base_service;
1233 bus_test_clients_foreach (check_service_created_foreach,
1241 warn_unexpected (connection, message, "ServiceCreated for base service");
1250 *base_service_p = base_service;
1251 base_service = NULL;
1256 dbus_message_unref (message);
1259 dbus_free (base_service);
1265 check_service_activated (BusContext *context,
1266 DBusConnection *connection,
1267 const char *activated_name,
1268 const char *base_service_name,
1269 DBusMessage *initial_message)
1271 DBusMessage *message;
1274 dbus_uint32_t activation_result;
1278 dbus_error_init (&error);
1280 message = initial_message;
1281 dbus_message_ref (message);
1283 if (dbus_message_is_signal (message,
1284 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1288 CheckServiceCreatedData scd;
1290 reget_service_name_arg:
1291 if (!dbus_message_get_args (message, &error,
1292 DBUS_TYPE_STRING, &service_name,
1295 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1297 dbus_error_free (&error);
1298 _dbus_wait_for_memory ();
1299 goto reget_service_name_arg;
1303 _dbus_warn ("Message %s doesn't have a service name: %s\n",
1306 dbus_error_free (&error);
1311 if (strcmp (service_name, activated_name) != 0)
1313 _dbus_warn ("Expected to see service %s created, saw %s instead\n",
1314 activated_name, service_name);
1315 dbus_free (service_name);
1319 scd.skip_connection = connection;
1321 scd.expected_service_name = service_name;
1322 bus_test_clients_foreach (check_service_created_foreach,
1325 dbus_free (service_name);
1330 dbus_message_unref (message);
1331 message = pop_message_waiting_for_memory (connection);
1332 if (message == NULL)
1334 _dbus_warn ("Expected a reply to %s, got nothing\n",
1341 warn_unexpected (connection, message, "ServiceCreated for the activated name");
1346 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
1348 warn_unexpected (connection, message, "reply to ActivateService");
1353 activation_result = 0;
1354 if (!dbus_message_get_args (message, &error,
1355 DBUS_TYPE_UINT32, &activation_result,
1358 if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1360 _dbus_warn ("Did not have activation result first argument to %s: %s\n",
1361 "ActivateService", error.message);
1362 dbus_error_free (&error);
1366 dbus_error_free (&error);
1370 if (activation_result == DBUS_ACTIVATION_REPLY_ACTIVATED)
1372 else if (activation_result == DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE)
1376 _dbus_warn ("Activation result was 0x%x, no good.\n",
1382 dbus_message_unref (message);
1385 if (!check_no_leftovers (context))
1387 _dbus_warn ("Messages were left over after verifying existent activation results\n");
1395 dbus_message_unref (message);
1401 check_service_deactivated (BusContext *context,
1402 DBusConnection *connection,
1403 const char *activated_name,
1404 const char *base_service)
1406 DBusMessage *message;
1409 CheckServiceDeletedData csdd;
1414 dbus_error_init (&error);
1416 /* Now we are expecting ServiceDeleted messages for the base
1417 * service and the activated_name. The base service
1418 * notification is required to come last.
1420 csdd.expected_service_name = activated_name;
1421 csdd.failed = FALSE;
1422 bus_test_clients_foreach (check_service_deleted_foreach,
1428 csdd.expected_service_name = base_service;
1429 csdd.failed = FALSE;
1430 bus_test_clients_foreach (check_service_deleted_foreach,
1440 dbus_message_unref (message);
1446 check_send_exit_to_service (BusContext *context,
1447 DBusConnection *connection,
1448 const char *service_name,
1449 const char *base_service)
1451 dbus_bool_t got_error;
1452 DBusMessage *message;
1453 dbus_uint32_t serial;
1456 _dbus_verbose ("Sending exit message to the test service\n");
1460 /* Kill off the test service by sending it a quit message */
1461 message = dbus_message_new_method_call (service_name,
1462 "/org/freedesktop/TestSuite",
1463 "org.freedesktop.TestSuite",
1466 if (message == NULL)
1468 /* Do this again; we still need the service to exit... */
1469 if (!check_send_exit_to_service (context, connection,
1470 service_name, base_service))
1476 if (!dbus_connection_send (connection, message, &serial))
1478 dbus_message_unref (message);
1480 /* Do this again; we still need the service to exit... */
1481 if (!check_send_exit_to_service (context, connection,
1482 service_name, base_service))
1488 dbus_message_unref (message);
1492 bus_test_run_clients_loop (TRUE);
1494 /* read it in and write it out to test service */
1495 bus_test_run_bus_loop (context, FALSE);
1497 /* see if we got an error during message bus dispatching */
1498 bus_test_run_clients_loop (FALSE);
1499 message = dbus_connection_borrow_message (connection);
1500 got_error = message != NULL && dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
1503 dbus_connection_return_message (connection, message);
1509 /* If no error, wait for the test service to exit */
1510 block_connection_until_message_from_bus (context, connection);
1512 bus_test_run_everything (context);
1517 message = pop_message_waiting_for_memory (connection);
1518 _dbus_assert (message != NULL);
1520 if (dbus_message_get_reply_serial (message) != serial)
1522 warn_unexpected (connection, message,
1523 "error with the correct reply serial");
1527 if (!dbus_message_is_error (message,
1528 DBUS_ERROR_NO_MEMORY))
1530 warn_unexpected (connection, message,
1531 "a no memory error from asking test service to exit");
1535 _dbus_verbose ("Got error %s when asking test service to exit\n",
1536 dbus_message_get_error_name (message));
1538 /* Do this again; we still need the service to exit... */
1539 if (!check_send_exit_to_service (context, connection,
1540 service_name, base_service))
1545 if (!check_service_deactivated (context, connection,
1546 service_name, base_service))
1549 /* Should now have a NoReply error from the Exit() method
1550 * call; it should have come after all the deactivation
1553 message = pop_message_waiting_for_memory (connection);
1555 if (message == NULL)
1557 warn_unexpected (connection, NULL,
1558 "reply to Exit() method call");
1561 if (!dbus_message_is_error (message,
1562 DBUS_ERROR_NO_REPLY))
1564 warn_unexpected (connection, NULL,
1565 "NoReply error from Exit() method call");
1569 if (dbus_message_get_reply_serial (message) != serial)
1571 warn_unexpected (connection, message,
1572 "error with the correct reply serial");
1576 _dbus_verbose ("Got error %s after test service exited\n",
1577 dbus_message_get_error_name (message));
1579 if (!check_no_leftovers (context))
1581 _dbus_warn ("Messages were left over after %s\n",
1582 _DBUS_FUNCTION_NAME);
1591 dbus_message_unref (message);
1597 check_got_error (BusContext *context,
1598 DBusConnection *connection,
1599 const char *first_error_name,
1602 DBusMessage *message;
1605 dbus_bool_t error_found;
1606 const char *error_name;
1610 message = pop_message_waiting_for_memory (connection);
1611 if (message == NULL)
1613 _dbus_warn ("Did not get an expected error\n");
1617 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
1619 warn_unexpected (connection, message, "an error");
1624 error_found = FALSE;
1626 va_start (ap, first_error_name);
1627 error_name = first_error_name;
1628 while (error_name != NULL)
1630 if (dbus_message_is_error (message, error_name))
1635 error_name = va_arg (ap, char*);
1641 _dbus_warn ("Expected error %s or other, got %s instead\n",
1643 dbus_message_get_error_name (message));
1651 dbus_message_unref (message);
1656 #define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"
1658 /* returns TRUE if the correct thing happens,
1659 * but the correct thing may include OOM errors.
1662 check_existent_service_activation (BusContext *context,
1663 DBusConnection *connection)
1665 DBusMessage *message;
1666 dbus_uint32_t serial;
1671 base_service = NULL;
1673 dbus_error_init (&error);
1675 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1676 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1677 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1680 if (message == NULL)
1683 if (!dbus_message_append_args (message,
1684 DBUS_TYPE_STRING, EXISTENT_SERVICE_NAME,
1685 DBUS_TYPE_UINT32, 0,
1688 dbus_message_unref (message);
1692 if (!dbus_connection_send (connection, message, &serial))
1694 dbus_message_unref (message);
1698 dbus_message_unref (message);
1701 bus_test_run_everything (context);
1703 /* now wait for the message bus to hear back from the activated
1706 block_connection_until_message_from_bus (context, connection);
1708 bus_test_run_everything (context);
1710 if (!dbus_connection_get_is_connected (connection))
1712 _dbus_verbose ("connection was disconnected\n");
1718 message = pop_message_waiting_for_memory (connection);
1719 if (message == NULL)
1721 _dbus_warn ("Did not receive any messages after %s %d on %p\n",
1722 "ActivateService", serial, connection);
1726 verbose_message_received (connection, message);
1727 _dbus_verbose (" (after sending %s)\n", "ActivateService");
1729 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1731 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1733 _dbus_warn ("Message has wrong sender %s\n",
1734 dbus_message_get_sender (message) ?
1735 dbus_message_get_sender (message) : "(none)");
1739 if (dbus_message_is_error (message,
1740 DBUS_ERROR_NO_MEMORY))
1742 ; /* good, this is a valid response */
1744 else if (dbus_message_is_error (message,
1745 DBUS_ERROR_SPAWN_CHILD_EXITED))
1747 ; /* good, this is expected also */
1751 _dbus_warn ("Did not expect error %s\n",
1752 dbus_message_get_error_name (message));
1758 dbus_bool_t got_service_deleted;
1759 dbus_bool_t got_error;
1761 if (!check_base_service_activated (context, connection,
1762 message, &base_service))
1765 dbus_message_unref (message);
1768 /* We may need to block here for the test service to exit or finish up */
1769 block_connection_until_message_from_bus (context, connection);
1771 message = dbus_connection_borrow_message (connection);
1772 if (message == NULL)
1774 _dbus_warn ("Did not receive any messages after base service creation notification\n");
1778 got_service_deleted = dbus_message_is_signal (message,
1779 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1781 got_error = dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
1783 dbus_connection_return_message (connection, message);
1788 if (!check_got_error (context, connection,
1789 DBUS_ERROR_SPAWN_CHILD_EXITED,
1790 DBUS_ERROR_NO_MEMORY,
1794 /* A service deleted should be coming along now after this error.
1795 * We can also get the error *after* the service deleted.
1797 got_service_deleted = TRUE;
1800 if (got_service_deleted)
1802 /* The service started up and got a base address, but then
1803 * failed to register under EXISTENT_SERVICE_NAME
1805 CheckServiceDeletedData csdd;
1807 csdd.expected_service_name = base_service;
1808 csdd.failed = FALSE;
1809 bus_test_clients_foreach (check_service_deleted_foreach,
1815 /* Now we should get an error about the service exiting
1816 * if we didn't get it before.
1820 block_connection_until_message_from_bus (context, connection);
1822 /* and process everything again */
1823 bus_test_run_everything (context);
1825 if (!check_got_error (context, connection,
1826 DBUS_ERROR_SPAWN_CHILD_EXITED,
1833 message = pop_message_waiting_for_memory (connection);
1834 if (message == NULL)
1836 _dbus_warn ("Failed to pop message we just put back! should have been a ServiceCreated\n");
1840 if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
1841 base_service, message))
1844 dbus_message_unref (message);
1848 if (!check_no_leftovers (context))
1850 _dbus_warn ("Messages were left over after successful activation\n");
1854 if (!check_send_exit_to_service (context, connection,
1855 EXISTENT_SERVICE_NAME, base_service))
1864 dbus_message_unref (message);
1867 dbus_free (base_service);
1872 /* returns TRUE if the correct thing happens,
1873 * but the correct thing may include OOM errors.
1876 check_segfault_service_activation (BusContext *context,
1877 DBusConnection *connection)
1879 DBusMessage *message;
1880 dbus_uint32_t serial;
1884 dbus_error_init (&error);
1886 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1887 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1888 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1891 if (message == NULL)
1894 if (!dbus_message_append_args (message,
1896 "org.freedesktop.DBus.TestSuiteSegfaultService",
1897 DBUS_TYPE_UINT32, 0,
1900 dbus_message_unref (message);
1904 if (!dbus_connection_send (connection, message, &serial))
1906 dbus_message_unref (message);
1910 dbus_message_unref (message);
1913 bus_test_run_everything (context);
1914 block_connection_until_message_from_bus (context, connection);
1915 bus_test_run_everything (context);
1917 if (!dbus_connection_get_is_connected (connection))
1919 _dbus_verbose ("connection was disconnected\n");
1925 message = pop_message_waiting_for_memory (connection);
1926 if (message == NULL)
1928 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1929 "ActivateService", serial, connection);
1933 verbose_message_received (connection, message);
1935 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1937 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1939 _dbus_warn ("Message has wrong sender %s\n",
1940 dbus_message_get_sender (message) ?
1941 dbus_message_get_sender (message) : "(none)");
1945 if (dbus_message_is_error (message,
1946 DBUS_ERROR_NO_MEMORY))
1948 ; /* good, this is a valid response */
1950 else if (dbus_message_is_error (message,
1951 DBUS_ERROR_SPAWN_CHILD_SIGNALED))
1953 ; /* good, this is expected also */
1957 warn_unexpected (connection, message, "not this error");
1964 _dbus_warn ("Did not expect to successfully activate segfault service\n");
1972 dbus_message_unref (message);
1980 BusContext *context;
1984 check_oom_check1_func (void *data)
1986 Check1Data *d = data;
1988 if (! (* d->func) (d->context))
1991 if (!check_no_leftovers (d->context))
1993 _dbus_warn ("Messages were left over, should be covered by test suite\n");
2001 check1_try_iterations (BusContext *context,
2002 const char *description,
2008 d.context = context;
2010 if (!_dbus_test_oom_handling (description, check_oom_check1_func,
2012 _dbus_assert_not_reached ("test failed");
2018 BusContext *context;
2019 DBusConnection *connection;
2023 check_oom_check2_func (void *data)
2025 Check2Data *d = data;
2027 if (! (* d->func) (d->context, d->connection))
2030 if (!check_no_leftovers (d->context))
2032 _dbus_warn ("Messages were left over, should be covered by test suite");
2040 check2_try_iterations (BusContext *context,
2041 DBusConnection *connection,
2042 const char *description,
2048 d.context = context;
2049 d.connection = connection;
2051 if (!_dbus_test_oom_handling (description, check_oom_check2_func,
2053 _dbus_assert_not_reached ("test failed");
2057 bus_dispatch_test (const DBusString *test_data_dir)
2059 BusContext *context;
2060 DBusConnection *foo;
2061 DBusConnection *bar;
2062 DBusConnection *baz;
2065 dbus_error_init (&error);
2067 context = bus_context_new_test (test_data_dir,
2068 "valid-config-files/debug-allow-all.conf");
2069 if (context == NULL)
2072 foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
2074 _dbus_assert_not_reached ("could not alloc connection");
2076 if (!bus_setup_debug_client (foo))
2077 _dbus_assert_not_reached ("could not set up connection");
2079 if (!check_hello_message (context, foo))
2080 _dbus_assert_not_reached ("hello message failed");
2082 if (!check_add_match_all (context, foo))
2083 _dbus_assert_not_reached ("AddMatch message failed");
2085 bar = dbus_connection_open ("debug-pipe:name=test-server", &error);
2087 _dbus_assert_not_reached ("could not alloc connection");
2089 if (!bus_setup_debug_client (bar))
2090 _dbus_assert_not_reached ("could not set up connection");
2092 if (!check_hello_message (context, bar))
2093 _dbus_assert_not_reached ("hello message failed");
2095 if (!check_add_match_all (context, bar))
2096 _dbus_assert_not_reached ("AddMatch message failed");
2098 baz = dbus_connection_open ("debug-pipe:name=test-server", &error);
2100 _dbus_assert_not_reached ("could not alloc connection");
2102 if (!bus_setup_debug_client (baz))
2103 _dbus_assert_not_reached ("could not set up connection");
2105 if (!check_hello_message (context, baz))
2106 _dbus_assert_not_reached ("hello message failed");
2108 if (!check_add_match_all (context, baz))
2109 _dbus_assert_not_reached ("AddMatch message failed");
2111 if (!check_no_leftovers (context))
2113 _dbus_warn ("Messages were left over after setting up initial connections");
2114 _dbus_assert_not_reached ("initial connection setup failed");
2117 check1_try_iterations (context, "create_and_hello",
2118 check_hello_connection);
2120 check2_try_iterations (context, foo, "nonexistent_service_activation",
2121 check_nonexistent_service_activation);
2123 check2_try_iterations (context, foo, "segfault_service_activation",
2124 check_segfault_service_activation);
2126 check2_try_iterations (context, foo, "existent_service_activation",
2127 check_existent_service_activation);
2129 _dbus_verbose ("Disconnecting foo, bar, and baz\n");
2131 kill_client_connection_unchecked (foo);
2132 kill_client_connection_unchecked (bar);
2133 kill_client_connection_unchecked (baz);
2135 bus_context_unref (context);
2141 bus_dispatch_sha1_test (const DBusString *test_data_dir)
2143 BusContext *context;
2144 DBusConnection *foo;
2147 dbus_error_init (&error);
2149 /* Test SHA1 authentication */
2150 _dbus_verbose ("Testing SHA1 context\n");
2152 context = bus_context_new_test (test_data_dir,
2153 "valid-config-files/debug-allow-all-sha1.conf");
2154 if (context == NULL)
2157 foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
2159 _dbus_assert_not_reached ("could not alloc connection");
2161 if (!bus_setup_debug_client (foo))
2162 _dbus_assert_not_reached ("could not set up connection");
2164 if (!check_hello_message (context, foo))
2165 _dbus_assert_not_reached ("hello message failed");
2167 if (!check_add_match_all (context, foo))
2168 _dbus_assert_not_reached ("addmatch message failed");
2170 if (!check_no_leftovers (context))
2172 _dbus_warn ("Messages were left over after setting up initial SHA-1 connection\n");
2173 _dbus_assert_not_reached ("initial connection setup failed");
2176 check1_try_iterations (context, "create_and_hello_sha1",
2177 check_hello_connection);
2179 kill_client_connection_unchecked (foo);
2181 bus_context_unref (context);
2186 #endif /* DBUS_BUILD_TESTS */