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"
32 #include <dbus/dbus-internals.h>
35 static int message_handler_slot = -1;
36 static int message_handler_slot_refcount;
41 DBusConnection *sender;
43 BusTransaction *transaction;
48 send_one_message (DBusConnection *connection, void *data)
50 SendMessageData *d = data;
52 if (!bus_context_check_security_policy (d->context,
57 return TRUE; /* silently don't send it */
59 if (!bus_transaction_send (d->transaction,
63 BUS_SET_OOM (d->error);
71 bus_dispatch_broadcast_message (BusTransaction *transaction,
72 DBusConnection *sender,
78 BusConnections *connections;
80 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
82 _dbus_assert (dbus_message_get_sender (message) != NULL);
84 connections = bus_transaction_get_connections (transaction);
86 dbus_error_init (&tmp_error);
88 d.context = bus_transaction_get_context (transaction);
90 d.transaction = transaction;
93 bus_connections_foreach_active (connections, send_one_message, &d);
95 if (dbus_error_is_set (&tmp_error))
97 dbus_move_error (&tmp_error, error);
105 bus_dispatch (DBusConnection *connection,
106 DBusMessage *message)
108 const char *sender, *service_name, *message_name;
110 BusTransaction *transaction;
114 dbus_error_init (&error);
116 context = bus_connection_get_context (connection);
117 _dbus_assert (context != NULL);
119 /* If we can't even allocate an OOM error, we just go to sleep
122 while (!bus_connection_preallocate_oom_error (connection))
123 _dbus_wait_for_memory ();
125 /* Ref connection in case we disconnect it at some point in here */
126 dbus_connection_ref (connection);
128 service_name = dbus_message_get_service (message);
129 message_name = dbus_message_get_name (message);
131 _dbus_assert (message_name != NULL); /* DBusMessageLoader is supposed to check this */
133 _dbus_verbose ("DISPATCH: %s to %s\n",
134 message_name, service_name ? service_name : "peer");
136 /* If service_name is NULL, this is a message to the bus daemon, not
137 * intended to actually go "on the bus"; e.g. a peer-to-peer
138 * ping. Handle these immediately, especially disconnection
139 * messages. There are no security policy checks on these.
141 if (service_name == NULL)
143 if (strcmp (message_name, DBUS_MESSAGE_LOCAL_DISCONNECT) == 0)
144 bus_connection_disconnected (connection);
146 /* DBusConnection also handles some of these automatically, we leave
152 _dbus_assert (service_name != NULL); /* this message is intended for bus routing */
154 /* Create our transaction */
155 transaction = bus_transaction_new (context);
156 if (transaction == NULL)
158 BUS_SET_OOM (&error);
162 /* Assign a sender to the message */
163 if (bus_connection_is_active (connection))
165 sender = bus_connection_get_name (connection);
166 _dbus_assert (sender != NULL);
168 if (!dbus_message_set_sender (message, sender))
170 BUS_SET_OOM (&error);
174 /* We need to refetch the service name here, because
175 * dbus_message_set_sender can cause the header to be
176 * reallocated, and thus the service_name pointer will become
179 service_name = dbus_message_get_service (message);
182 if (strcmp (service_name, DBUS_SERVICE_DBUS) == 0) /* to bus driver */
184 if (!bus_context_check_security_policy (context,
185 connection, NULL, message, &error))
188 if (!bus_driver_handle_message (connection, transaction, message, &error))
191 else if (!bus_connection_is_active (connection)) /* clients must talk to bus driver first */
193 _dbus_verbose ("Received message from non-registered client. Disconnecting.\n");
194 dbus_connection_disconnect (connection);
196 /* FIXME what if we un-special-case this service and just have a flag
197 * on services that all service owners will get messages to it, not just
200 else if (strcmp (service_name, DBUS_SERVICE_BROADCAST) == 0) /* spam! */
202 if (!bus_dispatch_broadcast_message (transaction, connection, message, &error))
205 else /* route to named service */
207 DBusString service_string;
209 BusRegistry *registry;
211 registry = bus_connection_get_registry (connection);
213 _dbus_string_init_const (&service_string, service_name);
214 service = bus_registry_lookup (registry, &service_string);
218 dbus_set_error (&error,
219 DBUS_ERROR_SERVICE_DOES_NOT_EXIST,
220 "Service \"%s\" does not exist",
226 DBusConnection *recipient;
228 recipient = bus_service_get_primary_owner (service);
229 _dbus_assert (recipient != NULL);
231 if (!bus_context_check_security_policy (context,
232 connection, recipient, message, &error))
235 /* Dispatch the message */
236 if (!bus_transaction_send (transaction, recipient, message))
238 BUS_SET_OOM (&error);
245 if (dbus_error_is_set (&error))
247 if (!dbus_connection_get_is_connected (connection))
249 /* If we disconnected it, we won't bother to send it any error
253 else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
255 bus_connection_send_oom_error (connection, message);
257 /* cancel transaction due to OOM */
258 if (transaction != NULL)
260 bus_transaction_cancel_and_free (transaction);
266 /* Try to send the real error, if no mem to do that, send
269 _dbus_assert (transaction != NULL);
271 if (!bus_transaction_send_error_reply (transaction, connection,
274 bus_connection_send_oom_error (connection, message);
276 /* cancel transaction due to OOM */
277 if (transaction != NULL)
279 bus_transaction_cancel_and_free (transaction);
285 dbus_error_free (&error);
288 if (transaction != NULL)
290 bus_transaction_execute_and_free (transaction);
293 dbus_connection_unref (connection);
296 static DBusHandlerResult
297 bus_dispatch_message_handler (DBusMessageHandler *handler,
298 DBusConnection *connection,
299 DBusMessage *message,
302 bus_dispatch (connection, message);
304 return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
308 message_handler_slot_ref (void)
310 if (message_handler_slot < 0)
312 message_handler_slot = dbus_connection_allocate_data_slot ();
314 if (message_handler_slot < 0)
317 _dbus_assert (message_handler_slot_refcount == 0);
320 message_handler_slot_refcount += 1;
326 message_handler_slot_unref (void)
328 _dbus_assert (message_handler_slot_refcount > 0);
330 message_handler_slot_refcount -= 1;
332 if (message_handler_slot_refcount == 0)
334 dbus_connection_free_data_slot (message_handler_slot);
335 message_handler_slot = -1;
340 free_message_handler (void *data)
342 DBusMessageHandler *handler = data;
344 _dbus_assert (message_handler_slot >= 0);
345 _dbus_assert (message_handler_slot_refcount > 0);
347 dbus_message_handler_unref (handler);
348 message_handler_slot_unref ();
352 bus_dispatch_add_connection (DBusConnection *connection)
354 DBusMessageHandler *handler;
356 if (!message_handler_slot_ref ())
359 handler = dbus_message_handler_new (bus_dispatch_message_handler, NULL, NULL);
362 message_handler_slot_unref ();
366 if (!dbus_connection_add_filter (connection, handler))
368 dbus_message_handler_unref (handler);
369 message_handler_slot_unref ();
374 _dbus_assert (message_handler_slot >= 0);
375 _dbus_assert (message_handler_slot_refcount > 0);
377 if (!dbus_connection_set_data (connection,
378 message_handler_slot,
380 free_message_handler))
382 dbus_message_handler_unref (handler);
383 message_handler_slot_unref ();
392 bus_dispatch_remove_connection (DBusConnection *connection)
394 /* Here we tell the bus driver that we want to get off. */
395 bus_driver_remove_connection (connection);
397 dbus_connection_set_data (connection,
398 message_handler_slot,
402 #ifdef DBUS_BUILD_TESTS
404 typedef dbus_bool_t (* Check1Func) (BusContext *context);
405 typedef dbus_bool_t (* Check2Func) (BusContext *context,
406 DBusConnection *connection);
408 static dbus_bool_t check_no_leftovers (BusContext *context);
411 block_connection_until_message_from_bus (BusContext *context,
412 DBusConnection *connection)
414 while (dbus_connection_get_dispatch_status (connection) ==
415 DBUS_DISPATCH_COMPLETE &&
416 dbus_connection_get_is_connected (connection))
418 bus_test_run_bus_loop (context, TRUE);
419 bus_test_run_clients_loop (FALSE);
423 /* compensate for fact that pop_message() can return #NULL due to OOM */
425 pop_message_waiting_for_memory (DBusConnection *connection)
427 while (dbus_connection_get_dispatch_status (connection) ==
428 DBUS_DISPATCH_NEED_MEMORY)
429 _dbus_wait_for_memory ();
431 return dbus_connection_pop_message (connection);
436 const char *expected_service_name;
438 } CheckServiceDeletedData;
441 check_service_deleted_foreach (DBusConnection *connection,
444 CheckServiceDeletedData *d = data;
445 DBusMessage *message;
449 dbus_error_init (&error);
453 message = pop_message_waiting_for_memory (connection);
456 _dbus_warn ("Did not receive a message on %p, expecting %s\n",
457 connection, DBUS_MESSAGE_SERVICE_DELETED);
460 else if (!dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_DELETED))
462 _dbus_warn ("Received message %s on %p, expecting %s\n",
463 dbus_message_get_name (message),
464 connection, DBUS_MESSAGE_SERVICE_DELETED);
469 if (!dbus_message_get_args (message, &error,
470 DBUS_TYPE_STRING, &service_name,
473 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
475 _dbus_verbose ("no memory to get service name arg\n");
479 _dbus_assert (dbus_error_is_set (&error));
480 _dbus_warn ("Did not get the expected single string argument\n");
484 else if (strcmp (service_name, d->expected_service_name) != 0)
486 _dbus_warn ("expected deletion of service %s, got deletion of %s\n",
487 d->expected_service_name,
496 dbus_free (service_name);
497 dbus_error_free (&error);
500 dbus_message_unref (message);
506 kill_client_connection (BusContext *context,
507 DBusConnection *connection)
511 CheckServiceDeletedData csdd;
513 _dbus_verbose ("killing connection %p\n", connection);
515 s = dbus_bus_get_base_service (connection);
516 _dbus_assert (s != NULL);
518 while ((base_service = _dbus_strdup (s)) == NULL)
519 _dbus_wait_for_memory ();
521 dbus_connection_ref (connection);
523 /* kick in the disconnect handler that unrefs the connection */
524 dbus_connection_disconnect (connection);
526 bus_test_run_everything (context);
528 _dbus_assert (bus_test_client_listed (connection));
530 /* Run disconnect handler in test.c */
531 if (bus_connection_dispatch_one_message (connection))
532 _dbus_assert_not_reached ("something received on connection being killed other than the disconnect");
534 _dbus_assert (!dbus_connection_get_is_connected (connection));
535 dbus_connection_unref (connection);
537 _dbus_assert (!bus_test_client_listed (connection));
539 csdd.expected_service_name = base_service;
542 bus_test_clients_foreach (check_service_deleted_foreach,
545 dbus_free (base_service);
548 _dbus_assert_not_reached ("didn't get the expected ServiceDeleted messages");
550 if (!check_no_leftovers (context))
551 _dbus_assert_not_reached ("stuff left in message queues after disconnecting a client");
555 kill_client_connection_unchecked (DBusConnection *connection)
557 /* This kills the connection without expecting it to affect
558 * the rest of the bus.
560 _dbus_verbose ("Unchecked kill of connection %p\n", connection);
562 dbus_connection_ref (connection);
563 dbus_connection_disconnect (connection);
564 /* dispatching disconnect handler will unref once */
565 if (bus_connection_dispatch_one_message (connection))
566 _dbus_assert_not_reached ("message other than disconnect dispatched after failure to register");
568 _dbus_assert (!bus_test_client_listed (connection));
569 dbus_connection_unref (connection);
575 } CheckNoMessagesData;
578 check_no_messages_foreach (DBusConnection *connection,
581 CheckNoMessagesData *d = data;
582 DBusMessage *message;
584 message = pop_message_waiting_for_memory (connection);
587 _dbus_warn ("Received message %s on %p, expecting no messages\n",
588 dbus_message_get_name (message), connection);
593 dbus_message_unref (message);
599 DBusConnection *skip_connection;
600 const char *expected_service_name;
602 } CheckServiceCreatedData;
605 check_service_created_foreach (DBusConnection *connection,
608 CheckServiceCreatedData *d = data;
609 DBusMessage *message;
613 if (connection == d->skip_connection)
616 dbus_error_init (&error);
620 message = pop_message_waiting_for_memory (connection);
623 _dbus_warn ("Did not receive a message on %p, expecting %s\n",
624 connection, DBUS_MESSAGE_SERVICE_CREATED);
627 else if (!dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_CREATED))
629 _dbus_warn ("Received message %s on %p, expecting %s\n",
630 dbus_message_get_name (message),
631 connection, DBUS_MESSAGE_SERVICE_CREATED);
636 if (!dbus_message_get_args (message, &error,
637 DBUS_TYPE_STRING, &service_name,
640 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
642 _dbus_verbose ("no memory to get service name arg\n");
646 _dbus_assert (dbus_error_is_set (&error));
647 _dbus_warn ("Did not get the expected single string argument\n");
651 else if (strcmp (service_name, d->expected_service_name) != 0)
653 _dbus_warn ("expected creation of service %s, got creation of %s\n",
654 d->expected_service_name,
663 dbus_free (service_name);
664 dbus_error_free (&error);
667 dbus_message_unref (message);
673 check_no_leftovers (BusContext *context)
675 CheckNoMessagesData nmd;
678 bus_test_clients_foreach (check_no_messages_foreach,
687 /* returns TRUE if the correct thing happens,
688 * but the correct thing may include OOM errors.
691 check_hello_message (BusContext *context,
692 DBusConnection *connection)
694 DBusMessage *message;
702 dbus_error_init (&error);
707 message = dbus_message_new (DBUS_MESSAGE_HELLO,
713 if (!dbus_connection_send (connection, message, &serial))
715 dbus_message_unref (message);
719 dbus_message_unref (message);
722 /* send our message */
723 bus_test_run_clients_loop (TRUE);
725 dbus_connection_ref (connection); /* because we may get disconnected */
726 block_connection_until_message_from_bus (context, connection);
728 if (!dbus_connection_get_is_connected (connection))
730 _dbus_verbose ("connection was disconnected\n");
732 dbus_connection_unref (connection);
737 dbus_connection_unref (connection);
739 message = pop_message_waiting_for_memory (connection);
742 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
743 DBUS_MESSAGE_HELLO, serial, connection);
747 _dbus_verbose ("Received %s on %p\n",
748 dbus_message_get_name (message), connection);
750 if (!dbus_message_sender_is (message, DBUS_SERVICE_DBUS))
752 _dbus_warn ("Message has wrong sender %s\n",
753 dbus_message_get_sender (message) ?
754 dbus_message_get_sender (message) : "(none)");
758 if (dbus_message_get_is_error (message))
760 if (dbus_message_name_is (message,
761 DBUS_ERROR_NO_MEMORY))
763 ; /* good, this is a valid response */
767 _dbus_warn ("Did not expect error %s\n",
768 dbus_message_get_name (message));
774 CheckServiceCreatedData scd;
776 if (dbus_message_name_is (message,
779 ; /* good, expected */
783 _dbus_warn ("Did not expect reply %s\n",
784 dbus_message_get_name (message));
788 retry_get_hello_name:
789 if (!dbus_message_get_args (message, &error,
790 DBUS_TYPE_STRING, &name,
793 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
795 _dbus_verbose ("no memory to get service name arg from hello\n");
796 dbus_error_free (&error);
797 _dbus_wait_for_memory ();
798 goto retry_get_hello_name;
802 _dbus_assert (dbus_error_is_set (&error));
803 _dbus_warn ("Did not get the expected single string argument to hello\n");
808 _dbus_verbose ("Got hello name: %s\n", name);
810 while (!dbus_bus_set_base_service (connection, name))
811 _dbus_wait_for_memory ();
813 scd.skip_connection = NULL;
815 scd.expected_service_name = name;
816 bus_test_clients_foreach (check_service_created_foreach,
822 /* Client should also have gotten ServiceAcquired */
823 dbus_message_unref (message);
824 message = pop_message_waiting_for_memory (connection);
827 _dbus_warn ("Expecting %s, got nothing\n",
828 DBUS_MESSAGE_SERVICE_ACQUIRED);
832 retry_get_acquired_name:
833 if (!dbus_message_get_args (message, &error,
834 DBUS_TYPE_STRING, &acquired,
837 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
839 _dbus_verbose ("no memory to get service name arg from acquired\n");
840 dbus_error_free (&error);
841 _dbus_wait_for_memory ();
842 goto retry_get_acquired_name;
846 _dbus_assert (dbus_error_is_set (&error));
847 _dbus_warn ("Did not get the expected single string argument to ServiceAcquired\n");
852 _dbus_verbose ("Got acquired name: %s\n", acquired);
854 if (strcmp (acquired, name) != 0)
856 _dbus_warn ("Acquired name is %s but expected %s\n",
862 if (!check_no_leftovers (context))
868 dbus_error_free (&error);
871 dbus_free (acquired);
874 dbus_message_unref (message);
879 /* returns TRUE if the correct thing happens,
880 * but the correct thing may include OOM errors.
883 check_hello_connection (BusContext *context)
885 DBusConnection *connection;
888 dbus_error_init (&error);
890 connection = dbus_connection_open ("debug-pipe:name=test-server", &error);
891 if (connection == NULL)
893 _DBUS_ASSERT_ERROR_IS_SET (&error);
894 dbus_error_free (&error);
898 if (!bus_setup_debug_client (connection))
900 dbus_connection_disconnect (connection);
901 dbus_connection_unref (connection);
905 if (!check_hello_message (context, connection))
908 if (dbus_bus_get_base_service (connection) == NULL)
910 /* We didn't successfully register, so we can't
911 * do the usual kill_client_connection() checks
913 kill_client_connection_unchecked (connection);
917 kill_client_connection (context, connection);
923 #define NONEXISTENT_SERVICE_NAME "test.this.service.does.not.exist.ewuoiurjdfxcvn"
925 /* returns TRUE if the correct thing happens,
926 * but the correct thing may include OOM errors.
929 check_nonexistent_service_activation (BusContext *context,
930 DBusConnection *connection)
932 DBusMessage *message;
937 dbus_error_init (&error);
939 message = dbus_message_new (DBUS_MESSAGE_ACTIVATE_SERVICE,
945 if (!dbus_message_append_args (message,
946 DBUS_TYPE_STRING, NONEXISTENT_SERVICE_NAME,
950 dbus_message_unref (message);
954 if (!dbus_connection_send (connection, message, &serial))
956 dbus_message_unref (message);
960 dbus_message_unref (message);
963 bus_test_run_everything (context);
964 block_connection_until_message_from_bus (context, connection);
965 bus_test_run_everything (context);
967 if (!dbus_connection_get_is_connected (connection))
969 _dbus_verbose ("connection was disconnected\n");
975 message = pop_message_waiting_for_memory (connection);
978 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
979 DBUS_MESSAGE_ACTIVATE_SERVICE, serial, connection);
983 _dbus_verbose ("Received %s on %p\n",
984 dbus_message_get_name (message), connection);
986 if (dbus_message_get_is_error (message))
988 if (!dbus_message_sender_is (message, DBUS_SERVICE_DBUS))
990 _dbus_warn ("Message has wrong sender %s\n",
991 dbus_message_get_sender (message) ?
992 dbus_message_get_sender (message) : "(none)");
996 if (dbus_message_name_is (message,
997 DBUS_ERROR_NO_MEMORY))
999 ; /* good, this is a valid response */
1001 else if (dbus_message_name_is (message,
1002 DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND))
1004 ; /* good, this is expected also */
1008 _dbus_warn ("Did not expect error %s\n",
1009 dbus_message_get_name (message));
1015 _dbus_warn ("Did not expect to successfully activate %s\n",
1016 NONEXISTENT_SERVICE_NAME);
1024 dbus_message_unref (message);
1030 check_base_service_activated (BusContext *context,
1031 DBusConnection *connection,
1032 DBusMessage *initial_message,
1033 char **base_service_p)
1035 DBusMessage *message;
1040 base_service = NULL;
1043 dbus_error_init (&error);
1045 message = initial_message;
1046 dbus_message_ref (message);
1048 if (dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_CREATED))
1051 CheckServiceCreatedData scd;
1053 reget_service_name_arg:
1054 if (!dbus_message_get_args (message, &error,
1055 DBUS_TYPE_STRING, &service_name,
1058 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1060 dbus_error_free (&error);
1061 _dbus_wait_for_memory ();
1062 goto reget_service_name_arg;
1066 _dbus_warn ("Message %s doesn't have a service name: %s\n",
1067 dbus_message_get_name (message),
1069 dbus_error_free (&error);
1074 if (*service_name != ':')
1076 _dbus_warn ("Expected base service activation, got \"%s\" instead\n",
1081 base_service = service_name;
1082 service_name = NULL;
1084 scd.skip_connection = connection;
1086 scd.expected_service_name = base_service;
1087 bus_test_clients_foreach (check_service_created_foreach,
1095 _dbus_warn ("Expected to get base service ServiceCreated, instead got %s\n",
1096 dbus_message_get_name (message));
1104 *base_service_p = base_service;
1105 base_service = NULL;
1110 dbus_message_unref (message);
1113 dbus_free (base_service);
1119 check_service_activated (BusContext *context,
1120 DBusConnection *connection,
1121 const char *activated_name,
1122 const char *base_service_name,
1123 DBusMessage *initial_message)
1125 DBusMessage *message;
1128 dbus_uint32_t activation_result;
1132 dbus_error_init (&error);
1134 message = initial_message;
1135 dbus_message_ref (message);
1137 if (dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_CREATED))
1140 CheckServiceCreatedData scd;
1142 reget_service_name_arg:
1143 if (!dbus_message_get_args (message, &error,
1144 DBUS_TYPE_STRING, &service_name,
1147 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1149 dbus_error_free (&error);
1150 _dbus_wait_for_memory ();
1151 goto reget_service_name_arg;
1155 _dbus_warn ("Message %s doesn't have a service name: %s\n",
1156 dbus_message_get_name (message),
1158 dbus_error_free (&error);
1163 if (strcmp (service_name, activated_name) != 0)
1165 _dbus_warn ("Expected to see service %s created, saw %s instead\n",
1166 activated_name, service_name);
1167 dbus_free (service_name);
1171 scd.skip_connection = connection;
1173 scd.expected_service_name = service_name;
1174 bus_test_clients_foreach (check_service_created_foreach,
1177 dbus_free (service_name);
1182 dbus_message_unref (message);
1183 message = pop_message_waiting_for_memory (connection);
1184 if (message == NULL)
1186 _dbus_warn ("Expected a reply to %s, got nothing\n",
1187 DBUS_MESSAGE_ACTIVATE_SERVICE);
1193 _dbus_warn ("Expected to get service %s ServiceCreated, instead got %s\n",
1194 activated_name, dbus_message_get_name (message));
1198 if (!dbus_message_name_is (message, DBUS_MESSAGE_ACTIVATE_SERVICE))
1200 _dbus_warn ("Expected reply to %s, got message %s instead\n",
1201 DBUS_MESSAGE_ACTIVATE_SERVICE,
1202 dbus_message_get_name (message));
1206 activation_result = 0;
1207 if (!dbus_message_get_args (message, &error,
1208 DBUS_TYPE_UINT32, &activation_result,
1211 if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1213 _dbus_warn ("Did not have activation result first argument to %s: %s\n",
1214 DBUS_MESSAGE_ACTIVATE_SERVICE, error.message);
1215 dbus_error_free (&error);
1219 dbus_error_free (&error);
1223 if (activation_result == DBUS_ACTIVATION_REPLY_ACTIVATED)
1225 else if (activation_result == DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE)
1229 _dbus_warn ("Activation result was 0x%x, no good.\n",
1235 dbus_message_unref (message);
1238 if (!check_no_leftovers (context))
1240 _dbus_warn ("Messages were left over after verifying existent activation results\n");
1248 dbus_message_unref (message);
1254 check_service_deactivated (BusContext *context,
1255 DBusConnection *connection,
1256 const char *activated_name,
1257 const char *base_service)
1259 DBusMessage *message;
1262 CheckServiceDeletedData csdd;
1267 dbus_error_init (&error);
1269 /* Now we are expecting ServiceDeleted messages for the base
1270 * service and the activated_name. The base service
1271 * notification is required to come last.
1273 csdd.expected_service_name = activated_name;
1274 csdd.failed = FALSE;
1275 bus_test_clients_foreach (check_service_deleted_foreach,
1281 csdd.expected_service_name = base_service;
1282 csdd.failed = FALSE;
1283 bus_test_clients_foreach (check_service_deleted_foreach,
1289 if (!check_no_leftovers (context))
1291 _dbus_warn ("Messages were left over after verifying results of service exiting\n");
1299 dbus_message_unref (message);
1305 check_send_exit_to_service (BusContext *context,
1306 DBusConnection *connection,
1307 const char *service_name,
1308 const char *base_service)
1310 dbus_bool_t got_error;
1311 DBusMessage *message;
1312 dbus_int32_t serial;
1315 _dbus_verbose ("Sending exit message to the test service\n");
1319 /* Kill off the test service by sending it a quit message */
1320 message = dbus_message_new ("org.freedesktop.DBus.TestSuiteExit",
1323 if (message == NULL)
1325 /* Do this again; we still need the service to exit... */
1326 if (!check_send_exit_to_service (context, connection,
1327 service_name, base_service))
1333 if (!dbus_connection_send (connection, message, &serial))
1335 dbus_message_unref (message);
1337 /* Do this again; we still need the service to exit... */
1338 if (!check_send_exit_to_service (context, connection,
1339 service_name, base_service))
1345 dbus_message_unref (message);
1349 bus_test_run_clients_loop (TRUE);
1351 /* read it in and write it out to test service */
1352 bus_test_run_bus_loop (context, FALSE);
1354 /* see if we got an error during message bus dispatching */
1355 bus_test_run_clients_loop (FALSE);
1356 message = dbus_connection_borrow_message (connection);
1357 got_error = message != NULL && dbus_message_get_is_error (message);
1360 dbus_connection_return_message (connection, message);
1366 /* If no error, wait for the test service to exit */
1367 block_connection_until_message_from_bus (context, connection);
1369 bus_test_run_everything (context);
1374 message = pop_message_waiting_for_memory (connection);
1375 _dbus_assert (message != NULL);
1377 if (!dbus_message_get_is_error (message))
1379 _dbus_warn ("expecting an error reply to asking test service to exit, got %s\n",
1380 dbus_message_get_name (message));
1383 else if (!dbus_message_name_is (message, DBUS_ERROR_NO_MEMORY))
1385 _dbus_warn ("not expecting error %s when asking test service to exit\n",
1386 dbus_message_get_name (message));
1390 _dbus_verbose ("Got error %s when asking test service to exit\n",
1391 dbus_message_get_name (message));
1393 /* Do this again; we still need the service to exit... */
1394 if (!check_send_exit_to_service (context, connection,
1395 service_name, base_service))
1400 if (!check_service_deactivated (context, connection,
1401 service_name, base_service))
1409 dbus_message_unref (message);
1415 check_got_error (BusContext *context,
1416 DBusConnection *connection,
1417 const char *first_error_name,
1420 DBusMessage *message;
1423 dbus_bool_t error_found;
1424 const char *error_name;
1428 message = pop_message_waiting_for_memory (connection);
1429 if (message == NULL)
1431 _dbus_warn ("Did not get an expected error\n");
1435 if (!dbus_message_get_is_error (message))
1437 _dbus_warn ("Expected an error, got %s\n",
1438 dbus_message_get_name (message));
1442 error_found = FALSE;
1444 va_start (ap, first_error_name);
1445 error_name = first_error_name;
1446 while (error_name != NULL)
1448 if (dbus_message_name_is (message, error_name))
1453 error_name = va_arg (ap, char*);
1459 _dbus_warn ("Expected error %s or other, got %s instead\n",
1461 dbus_message_get_name (message));
1469 dbus_message_unref (message);
1474 #define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"
1476 /* returns TRUE if the correct thing happens,
1477 * but the correct thing may include OOM errors.
1480 check_existent_service_activation (BusContext *context,
1481 DBusConnection *connection)
1483 DBusMessage *message;
1484 dbus_int32_t serial;
1489 base_service = NULL;
1491 dbus_error_init (&error);
1493 message = dbus_message_new (DBUS_MESSAGE_ACTIVATE_SERVICE,
1496 if (message == NULL)
1499 if (!dbus_message_append_args (message,
1500 DBUS_TYPE_STRING, EXISTENT_SERVICE_NAME,
1501 DBUS_TYPE_UINT32, 0,
1504 dbus_message_unref (message);
1508 if (!dbus_connection_send (connection, message, &serial))
1510 dbus_message_unref (message);
1514 dbus_message_unref (message);
1517 bus_test_run_everything (context);
1519 /* now wait for the message bus to hear back from the activated
1522 block_connection_until_message_from_bus (context, connection);
1524 bus_test_run_everything (context);
1526 if (!dbus_connection_get_is_connected (connection))
1528 _dbus_verbose ("connection was disconnected\n");
1534 message = pop_message_waiting_for_memory (connection);
1535 if (message == NULL)
1537 _dbus_warn ("Did not receive any messages after %s %d on %p\n",
1538 DBUS_MESSAGE_ACTIVATE_SERVICE, serial, connection);
1542 _dbus_verbose ("Received %s on %p after sending %s\n",
1543 dbus_message_get_name (message), connection,
1544 DBUS_MESSAGE_ACTIVATE_SERVICE);
1546 if (dbus_message_get_is_error (message))
1548 if (!dbus_message_sender_is (message, DBUS_SERVICE_DBUS))
1550 _dbus_warn ("Message has wrong sender %s\n",
1551 dbus_message_get_sender (message) ?
1552 dbus_message_get_sender (message) : "(none)");
1556 if (dbus_message_name_is (message,
1557 DBUS_ERROR_NO_MEMORY))
1559 ; /* good, this is a valid response */
1561 else if (dbus_message_name_is (message,
1562 DBUS_ERROR_SPAWN_CHILD_EXITED))
1564 ; /* good, this is expected also */
1568 _dbus_warn ("Did not expect error %s\n",
1569 dbus_message_get_name (message));
1575 dbus_bool_t got_service_deleted;
1576 dbus_bool_t got_error;
1578 if (!check_base_service_activated (context, connection,
1579 message, &base_service))
1582 dbus_message_unref (message);
1585 /* We may need to block here for the test service to exit or finish up */
1586 block_connection_until_message_from_bus (context, connection);
1588 message = dbus_connection_borrow_message (connection);
1589 if (message == NULL)
1591 _dbus_warn ("Did not receive any messages after base service creation notification\n");
1595 got_service_deleted = dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_DELETED);
1596 got_error = dbus_message_get_is_error (message);
1598 dbus_connection_return_message (connection, message);
1603 if (!check_got_error (context, connection,
1604 DBUS_ERROR_SPAWN_CHILD_EXITED,
1605 DBUS_ERROR_NO_MEMORY,
1609 /* A service deleted should be coming along now after this error.
1610 * We can also get the error *after* the service deleted.
1612 got_service_deleted = TRUE;
1615 if (got_service_deleted)
1617 /* The service started up and got a base address, but then
1618 * failed to register under EXISTENT_SERVICE_NAME
1620 CheckServiceDeletedData csdd;
1622 csdd.expected_service_name = base_service;
1623 csdd.failed = FALSE;
1624 bus_test_clients_foreach (check_service_deleted_foreach,
1630 /* Now we should get an error about the service exiting
1631 * if we didn't get it before.
1635 block_connection_until_message_from_bus (context, connection);
1637 /* and process everything again */
1638 bus_test_run_everything (context);
1640 if (!check_got_error (context, connection,
1641 DBUS_ERROR_SPAWN_CHILD_EXITED,
1648 message = pop_message_waiting_for_memory (connection);
1649 if (message == NULL)
1651 _dbus_warn ("Failed to pop message we just put back! should have been a ServiceCreated\n");
1655 if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
1656 base_service, message))
1659 dbus_message_unref (message);
1663 if (!check_no_leftovers (context))
1665 _dbus_warn ("Messages were left over after successful activation\n");
1669 if (!check_send_exit_to_service (context, connection,
1670 EXISTENT_SERVICE_NAME, base_service))
1679 dbus_message_unref (message);
1682 dbus_free (base_service);
1687 /* returns TRUE if the correct thing happens,
1688 * but the correct thing may include OOM errors.
1691 check_segfault_service_activation (BusContext *context,
1692 DBusConnection *connection)
1694 DBusMessage *message;
1695 dbus_int32_t serial;
1699 dbus_error_init (&error);
1701 message = dbus_message_new (DBUS_MESSAGE_ACTIVATE_SERVICE,
1704 if (message == NULL)
1707 if (!dbus_message_append_args (message,
1709 "org.freedesktop.DBus.TestSuiteSegfaultService",
1710 DBUS_TYPE_UINT32, 0,
1713 dbus_message_unref (message);
1717 if (!dbus_connection_send (connection, message, &serial))
1719 dbus_message_unref (message);
1723 dbus_message_unref (message);
1726 bus_test_run_everything (context);
1727 block_connection_until_message_from_bus (context, connection);
1728 bus_test_run_everything (context);
1730 if (!dbus_connection_get_is_connected (connection))
1732 _dbus_verbose ("connection was disconnected\n");
1738 message = pop_message_waiting_for_memory (connection);
1739 if (message == NULL)
1741 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1742 DBUS_MESSAGE_ACTIVATE_SERVICE, serial, connection);
1746 _dbus_verbose ("Received %s on %p\n",
1747 dbus_message_get_name (message), connection);
1749 if (dbus_message_get_is_error (message))
1751 if (!dbus_message_sender_is (message, DBUS_SERVICE_DBUS))
1753 _dbus_warn ("Message has wrong sender %s\n",
1754 dbus_message_get_sender (message) ?
1755 dbus_message_get_sender (message) : "(none)");
1759 if (dbus_message_name_is (message,
1760 DBUS_ERROR_NO_MEMORY))
1762 ; /* good, this is a valid response */
1764 else if (dbus_message_name_is (message,
1765 DBUS_ERROR_SPAWN_CHILD_SIGNALED))
1767 ; /* good, this is expected also */
1771 _dbus_warn ("Did not expect error %s\n",
1772 dbus_message_get_name (message));
1778 _dbus_warn ("Did not expect to successfully activate segfault service\n");
1786 dbus_message_unref (message);
1794 BusContext *context;
1798 check_oom_check1_func (void *data)
1800 Check1Data *d = data;
1802 if (! (* d->func) (d->context))
1805 if (!check_no_leftovers (d->context))
1807 _dbus_warn ("Messages were left over, should be covered by test suite\n");
1815 check1_try_iterations (BusContext *context,
1816 const char *description,
1822 d.context = context;
1824 if (!_dbus_test_oom_handling (description, check_oom_check1_func,
1826 _dbus_assert_not_reached ("test failed");
1832 BusContext *context;
1833 DBusConnection *connection;
1837 check_oom_check2_func (void *data)
1839 Check2Data *d = data;
1841 if (! (* d->func) (d->context, d->connection))
1844 if (!check_no_leftovers (d->context))
1846 _dbus_warn ("Messages were left over, should be covered by test suite");
1854 check2_try_iterations (BusContext *context,
1855 DBusConnection *connection,
1856 const char *description,
1862 d.context = context;
1863 d.connection = connection;
1865 if (!_dbus_test_oom_handling (description, check_oom_check2_func,
1867 _dbus_assert_not_reached ("test failed");
1871 bus_dispatch_test (const DBusString *test_data_dir)
1873 BusContext *context;
1874 DBusConnection *foo;
1875 DBusConnection *bar;
1876 DBusConnection *baz;
1879 dbus_error_init (&error);
1881 context = bus_context_new_test (test_data_dir,
1882 "valid-config-files/debug-allow-all.conf");
1883 if (context == NULL)
1886 foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
1888 _dbus_assert_not_reached ("could not alloc connection");
1890 if (!bus_setup_debug_client (foo))
1891 _dbus_assert_not_reached ("could not set up connection");
1893 if (!check_hello_message (context, foo))
1894 _dbus_assert_not_reached ("hello message failed");
1896 bar = dbus_connection_open ("debug-pipe:name=test-server", &error);
1898 _dbus_assert_not_reached ("could not alloc connection");
1900 if (!bus_setup_debug_client (bar))
1901 _dbus_assert_not_reached ("could not set up connection");
1903 if (!check_hello_message (context, bar))
1904 _dbus_assert_not_reached ("hello message failed");
1906 baz = dbus_connection_open ("debug-pipe:name=test-server", &error);
1908 _dbus_assert_not_reached ("could not alloc connection");
1910 if (!bus_setup_debug_client (baz))
1911 _dbus_assert_not_reached ("could not set up connection");
1913 if (!check_hello_message (context, baz))
1914 _dbus_assert_not_reached ("hello message failed");
1916 if (!check_no_leftovers (context))
1918 _dbus_warn ("Messages were left over after setting up initial connections");
1919 _dbus_assert_not_reached ("initial connection setup failed");
1922 check1_try_iterations (context, "create_and_hello",
1923 check_hello_connection);
1925 check2_try_iterations (context, foo, "nonexistent_service_activation",
1926 check_nonexistent_service_activation);
1928 check2_try_iterations (context, foo, "segfault_service_activation",
1929 check_segfault_service_activation);
1931 check2_try_iterations (context, foo, "existent_service_activation",
1932 check_existent_service_activation);
1934 _dbus_verbose ("Disconnecting foo, bar, and baz\n");
1936 kill_client_connection_unchecked (foo);
1937 kill_client_connection_unchecked (bar);
1938 kill_client_connection_unchecked (baz);
1940 bus_context_unref (context);
1946 bus_dispatch_sha1_test (const DBusString *test_data_dir)
1948 BusContext *context;
1949 DBusConnection *foo;
1952 dbus_error_init (&error);
1954 /* Test SHA1 authentication */
1955 _dbus_verbose ("Testing SHA1 context\n");
1957 context = bus_context_new_test (test_data_dir,
1958 "valid-config-files/debug-allow-all-sha1.conf");
1959 if (context == NULL)
1962 foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
1964 _dbus_assert_not_reached ("could not alloc connection");
1966 if (!bus_setup_debug_client (foo))
1967 _dbus_assert_not_reached ("could not set up connection");
1969 if (!check_hello_message (context, foo))
1970 _dbus_assert_not_reached ("hello message failed");
1972 if (!check_no_leftovers (context))
1974 _dbus_warn ("Messages were left over after setting up initial SHA-1 connection\n");
1975 _dbus_assert_not_reached ("initial connection setup failed");
1978 check1_try_iterations (context, "create_and_hello_sha1",
1979 check_hello_connection);
1981 kill_client_connection_unchecked (foo);
1983 bus_context_unref (context);
1988 #endif /* DBUS_BUILD_TESTS */