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 BusTransaction *transaction;
46 send_one_message (DBusConnection *connection, void *data)
48 SendMessageData *d = data;
50 if (!bus_connection_is_active (connection))
53 if (!bus_transaction_send_message (d->transaction,
57 BUS_SET_OOM (d->error);
65 bus_dispatch_broadcast_message (BusTransaction *transaction,
71 BusConnections *connections;
73 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
75 _dbus_assert (dbus_message_get_sender (message) != NULL);
77 connections = bus_transaction_get_connections (transaction);
79 dbus_error_init (&tmp_error);
81 d.transaction = transaction;
84 bus_connections_foreach (connections, send_one_message, &d);
86 if (dbus_error_is_set (&tmp_error))
88 dbus_move_error (&tmp_error, error);
96 send_service_nonexistent_error (BusTransaction *transaction,
97 DBusConnection *connection,
98 const char *service_name,
99 DBusMessage *in_reply_to,
102 DBusMessage *error_reply;
103 DBusString error_message;
104 const char *error_str;
106 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
108 /* Trying to send a message to a non-existant service,
109 * bounce back an error message.
112 if (!_dbus_string_init (&error_message))
118 if (!_dbus_string_append (&error_message, "Service \"") ||
119 !_dbus_string_append (&error_message, service_name) ||
120 !_dbus_string_append (&error_message, "\" does not exist"))
122 _dbus_string_free (&error_message);
127 error_str = _dbus_string_get_const_data (&error_message);
128 error_reply = dbus_message_new_error_reply (in_reply_to,
129 DBUS_ERROR_SERVICE_DOES_NOT_EXIST,
132 _dbus_string_free (&error_message);
134 if (error_reply == NULL)
140 if (!dbus_message_set_sender (error_reply, DBUS_SERVICE_DBUS))
142 dbus_message_unref (error_reply);
147 if (!bus_transaction_send_message (transaction, connection, error_reply))
149 dbus_message_unref (error_reply);
154 dbus_message_unref (error_reply);
160 bus_dispatch (DBusConnection *connection,
161 DBusMessage *message)
163 const char *sender, *service_name, *message_name;
165 BusTransaction *transaction;
169 dbus_error_init (&error);
171 context = bus_connection_get_context (connection);
172 _dbus_assert (context != NULL);
174 /* If we can't even allocate an OOM error, we just go to sleep
177 while (!bus_connection_preallocate_oom_error (connection))
178 _dbus_wait_for_memory ();
180 /* Ref connection in case we disconnect it at some point in here */
181 dbus_connection_ref (connection);
183 service_name = dbus_message_get_service (message);
184 message_name = dbus_message_get_name (message);
186 _dbus_assert (message_name != NULL); /* DBusMessageLoader is supposed to check this */
188 _dbus_verbose ("DISPATCH: %s to %s\n",
189 message_name, service_name ? service_name : "peer");
191 /* If service_name is NULL, this is a message to the bus daemon, not intended
192 * to actually go "on the bus"; e.g. a peer-to-peer ping. Handle these
193 * immediately, especially disconnection messages.
195 if (service_name == NULL)
197 if (strcmp (message_name, DBUS_MESSAGE_LOCAL_DISCONNECT) == 0)
198 bus_connection_disconnected (connection);
200 /* DBusConnection also handles some of these automatically, we leave
206 _dbus_assert (service_name != NULL); /* this message is intended for bus routing */
208 /* Create our transaction */
209 transaction = bus_transaction_new (context);
210 if (transaction == NULL)
212 BUS_SET_OOM (&error);
216 /* Assign a sender to the message */
217 if (bus_connection_is_active (connection))
219 sender = bus_connection_get_name (connection);
220 _dbus_assert (sender != NULL);
222 if (!dbus_message_set_sender (message, sender))
224 BUS_SET_OOM (&error);
228 /* We need to refetch the service name here, because
229 * dbus_message_set_sender can cause the header to be
230 * reallocated, and thus the service_name pointer will become
233 service_name = dbus_message_get_service (message);
236 if (strcmp (service_name, DBUS_SERVICE_DBUS) == 0) /* to bus driver */
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);
246 /* FIXME what if we un-special-case this service and just have a flag
247 * on services that all service owners will get messages to it, not just
250 else if (strcmp (service_name, DBUS_SERVICE_BROADCAST) == 0) /* spam! */
252 if (!bus_dispatch_broadcast_message (transaction, message, &error))
255 else /* route to named service */
257 DBusString service_string;
259 BusRegistry *registry;
261 registry = bus_connection_get_registry (connection);
263 _dbus_string_init_const (&service_string, service_name);
264 service = bus_registry_lookup (registry, &service_string);
268 if (!send_service_nonexistent_error (transaction, connection,
275 _dbus_assert (bus_service_get_primary_owner (service) != NULL);
277 /* Dispatch the message */
278 if (!bus_transaction_send_message (transaction,
279 bus_service_get_primary_owner (service),
282 BUS_SET_OOM (&error);
289 if (dbus_error_is_set (&error))
291 if (!dbus_connection_get_is_connected (connection))
293 /* If we disconnected it, we won't bother to send it any error
297 else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
299 bus_connection_send_oom_error (connection, message);
301 /* cancel transaction due to OOM */
302 if (transaction != NULL)
304 bus_transaction_cancel_and_free (transaction);
310 /* Try to send the real error, if no mem to do that, send
313 _dbus_assert (transaction != NULL);
315 if (!bus_transaction_send_error_reply (transaction, connection,
318 bus_connection_send_oom_error (connection, message);
320 /* cancel transaction due to OOM */
321 if (transaction != NULL)
323 bus_transaction_cancel_and_free (transaction);
329 dbus_error_free (&error);
332 if (transaction != NULL)
334 bus_transaction_execute_and_free (transaction);
337 dbus_connection_unref (connection);
340 static DBusHandlerResult
341 bus_dispatch_message_handler (DBusMessageHandler *handler,
342 DBusConnection *connection,
343 DBusMessage *message,
346 bus_dispatch (connection, message);
348 return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
352 message_handler_slot_ref (void)
354 if (message_handler_slot < 0)
356 message_handler_slot = dbus_connection_allocate_data_slot ();
358 if (message_handler_slot < 0)
361 _dbus_assert (message_handler_slot_refcount == 0);
364 message_handler_slot_refcount += 1;
370 message_handler_slot_unref (void)
372 _dbus_assert (message_handler_slot_refcount > 0);
374 message_handler_slot_refcount -= 1;
376 if (message_handler_slot_refcount == 0)
378 dbus_connection_free_data_slot (message_handler_slot);
379 message_handler_slot = -1;
384 free_message_handler (void *data)
386 DBusMessageHandler *handler = data;
388 _dbus_assert (message_handler_slot >= 0);
389 _dbus_assert (message_handler_slot_refcount > 0);
391 dbus_message_handler_unref (handler);
392 message_handler_slot_unref ();
396 bus_dispatch_add_connection (DBusConnection *connection)
398 DBusMessageHandler *handler;
400 if (!message_handler_slot_ref ())
403 handler = dbus_message_handler_new (bus_dispatch_message_handler, NULL, NULL);
406 message_handler_slot_unref ();
410 if (!dbus_connection_add_filter (connection, handler))
412 dbus_message_handler_unref (handler);
413 message_handler_slot_unref ();
418 _dbus_assert (message_handler_slot >= 0);
419 _dbus_assert (message_handler_slot_refcount > 0);
421 if (!dbus_connection_set_data (connection,
422 message_handler_slot,
424 free_message_handler))
426 dbus_message_handler_unref (handler);
427 message_handler_slot_unref ();
436 bus_dispatch_remove_connection (DBusConnection *connection)
438 /* Here we tell the bus driver that we want to get off. */
439 bus_driver_remove_connection (connection);
441 dbus_connection_set_data (connection,
442 message_handler_slot,
446 #ifdef DBUS_BUILD_TESTS
448 typedef dbus_bool_t (* Check1Func) (BusContext *context);
449 typedef dbus_bool_t (* Check2Func) (BusContext *context,
450 DBusConnection *connection);
452 static dbus_bool_t check_no_leftovers (BusContext *context);
455 block_connection_until_message_from_bus (BusContext *context,
456 DBusConnection *connection)
458 while (dbus_connection_get_dispatch_status (connection) ==
459 DBUS_DISPATCH_COMPLETE &&
460 dbus_connection_get_is_connected (connection))
462 bus_test_run_bus_loop (context, TRUE);
463 bus_test_run_clients_loop (FALSE);
467 /* compensate for fact that pop_message() can return #NULL due to OOM */
469 pop_message_waiting_for_memory (DBusConnection *connection)
471 while (dbus_connection_get_dispatch_status (connection) ==
472 DBUS_DISPATCH_NEED_MEMORY)
473 _dbus_wait_for_memory ();
475 return dbus_connection_pop_message (connection);
480 const char *expected_service_name;
482 } CheckServiceDeletedData;
485 check_service_deleted_foreach (DBusConnection *connection,
488 CheckServiceDeletedData *d = data;
489 DBusMessage *message;
493 dbus_error_init (&error);
497 message = pop_message_waiting_for_memory (connection);
500 _dbus_warn ("Did not receive a message on %p, expecting %s\n",
501 connection, DBUS_MESSAGE_SERVICE_DELETED);
504 else if (!dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_DELETED))
506 _dbus_warn ("Received message %s on %p, expecting %s\n",
507 dbus_message_get_name (message),
508 connection, DBUS_MESSAGE_SERVICE_DELETED);
513 if (!dbus_message_get_args (message, &error,
514 DBUS_TYPE_STRING, &service_name,
517 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
519 _dbus_verbose ("no memory to get service name arg\n");
523 _dbus_assert (dbus_error_is_set (&error));
524 _dbus_warn ("Did not get the expected single string argument\n");
528 else if (strcmp (service_name, d->expected_service_name) != 0)
530 _dbus_warn ("expected deletion of service %s, got deletion of %s\n",
531 d->expected_service_name,
540 dbus_free (service_name);
541 dbus_error_free (&error);
544 dbus_message_unref (message);
550 kill_client_connection (BusContext *context,
551 DBusConnection *connection)
555 CheckServiceDeletedData csdd;
557 _dbus_verbose ("killing connection %p\n", connection);
559 s = dbus_bus_get_base_service (connection);
560 _dbus_assert (s != NULL);
562 while ((base_service = _dbus_strdup (s)) == NULL)
563 _dbus_wait_for_memory ();
565 dbus_connection_ref (connection);
567 /* kick in the disconnect handler that unrefs the connection */
568 dbus_connection_disconnect (connection);
570 bus_test_run_everything (context);
572 _dbus_assert (bus_test_client_listed (connection));
574 /* Run disconnect handler in test.c */
575 if (bus_connection_dispatch_one_message (connection))
576 _dbus_assert_not_reached ("something received on connection being killed other than the disconnect");
578 _dbus_assert (!dbus_connection_get_is_connected (connection));
579 dbus_connection_unref (connection);
581 _dbus_assert (!bus_test_client_listed (connection));
583 csdd.expected_service_name = base_service;
586 bus_test_clients_foreach (check_service_deleted_foreach,
589 dbus_free (base_service);
592 _dbus_assert_not_reached ("didn't get the expected ServiceDeleted messages");
594 if (!check_no_leftovers (context))
595 _dbus_assert_not_reached ("stuff left in message queues after disconnecting a client");
599 kill_client_connection_unchecked (DBusConnection *connection)
601 /* This kills the connection without expecting it to affect
602 * the rest of the bus.
604 _dbus_verbose ("Unchecked kill of connection %p\n", connection);
606 dbus_connection_ref (connection);
607 dbus_connection_disconnect (connection);
608 /* dispatching disconnect handler will unref once */
609 if (bus_connection_dispatch_one_message (connection))
610 _dbus_assert_not_reached ("message other than disconnect dispatched after failure to register");
611 dbus_connection_unref (connection);
612 _dbus_assert (!bus_test_client_listed (connection));
618 } CheckNoMessagesData;
621 check_no_messages_foreach (DBusConnection *connection,
624 CheckNoMessagesData *d = data;
625 DBusMessage *message;
627 message = pop_message_waiting_for_memory (connection);
630 _dbus_warn ("Received message %s on %p, expecting no messages\n",
631 dbus_message_get_name (message), connection);
636 dbus_message_unref (message);
642 DBusConnection *skip_connection;
643 const char *expected_service_name;
645 } CheckServiceCreatedData;
648 check_service_created_foreach (DBusConnection *connection,
651 CheckServiceCreatedData *d = data;
652 DBusMessage *message;
656 if (connection == d->skip_connection)
659 dbus_error_init (&error);
663 message = pop_message_waiting_for_memory (connection);
666 _dbus_warn ("Did not receive a message on %p, expecting %s\n",
667 connection, DBUS_MESSAGE_SERVICE_CREATED);
670 else if (!dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_CREATED))
672 _dbus_warn ("Received message %s on %p, expecting %s\n",
673 dbus_message_get_name (message),
674 connection, DBUS_MESSAGE_SERVICE_CREATED);
679 if (!dbus_message_get_args (message, &error,
680 DBUS_TYPE_STRING, &service_name,
683 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
685 _dbus_verbose ("no memory to get service name arg\n");
689 _dbus_assert (dbus_error_is_set (&error));
690 _dbus_warn ("Did not get the expected single string argument\n");
694 else if (strcmp (service_name, d->expected_service_name) != 0)
696 _dbus_warn ("expected creation of service %s, got creation of %s\n",
697 d->expected_service_name,
706 dbus_free (service_name);
707 dbus_error_free (&error);
710 dbus_message_unref (message);
716 check_no_leftovers (BusContext *context)
718 CheckNoMessagesData nmd;
721 bus_test_clients_foreach (check_no_messages_foreach,
730 /* returns TRUE if the correct thing happens,
731 * but the correct thing may include OOM errors.
734 check_hello_message (BusContext *context,
735 DBusConnection *connection)
737 DBusMessage *message;
744 dbus_error_init (&error);
748 message = dbus_message_new (DBUS_SERVICE_DBUS,
754 if (!dbus_connection_send (connection, message, &serial))
756 dbus_message_unref (message);
760 dbus_message_unref (message);
763 bus_test_run_everything (context);
765 if (!dbus_connection_get_is_connected (connection))
767 _dbus_verbose ("connection was disconnected\n");
773 message = pop_message_waiting_for_memory (connection);
776 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
777 DBUS_MESSAGE_HELLO, serial, connection);
781 _dbus_verbose ("Received %s on %p\n",
782 dbus_message_get_name (message), connection);
784 if (!dbus_message_sender_is (message, DBUS_SERVICE_DBUS))
786 _dbus_warn ("Message has wrong sender %s\n",
787 dbus_message_get_sender (message) ?
788 dbus_message_get_sender (message) : "(none)");
792 if (dbus_message_get_is_error (message))
794 if (dbus_message_name_is (message,
795 DBUS_ERROR_NO_MEMORY))
797 ; /* good, this is a valid response */
801 _dbus_warn ("Did not expect error %s\n",
802 dbus_message_get_name (message));
808 CheckServiceCreatedData scd;
810 if (dbus_message_name_is (message,
813 ; /* good, expected */
817 _dbus_warn ("Did not expect reply %s\n",
818 dbus_message_get_name (message));
822 retry_get_hello_name:
823 if (!dbus_message_get_args (message, &error,
824 DBUS_TYPE_STRING, &name,
827 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
829 _dbus_verbose ("no memory to get service name arg from hello\n");
830 dbus_error_free (&error);
831 _dbus_wait_for_memory ();
832 goto retry_get_hello_name;
836 _dbus_assert (dbus_error_is_set (&error));
837 _dbus_warn ("Did not get the expected single string argument to hello\n");
842 _dbus_verbose ("Got hello name: %s\n", name);
844 while (!dbus_bus_set_base_service (connection, name))
845 _dbus_wait_for_memory ();
847 scd.skip_connection = NULL;
849 scd.expected_service_name = name;
850 bus_test_clients_foreach (check_service_created_foreach,
856 /* Client should also have gotten ServiceAcquired */
857 dbus_message_unref (message);
858 message = pop_message_waiting_for_memory (connection);
861 _dbus_warn ("Expecting %s, got nothing\n",
862 DBUS_MESSAGE_SERVICE_ACQUIRED);
866 retry_get_acquired_name:
867 if (!dbus_message_get_args (message, &error,
868 DBUS_TYPE_STRING, &acquired,
871 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
873 _dbus_verbose ("no memory to get service name arg from acquired\n");
874 dbus_error_free (&error);
875 _dbus_wait_for_memory ();
876 goto retry_get_acquired_name;
880 _dbus_assert (dbus_error_is_set (&error));
881 _dbus_warn ("Did not get the expected single string argument to ServiceAcquired\n");
886 _dbus_verbose ("Got acquired name: %s\n", acquired);
888 if (strcmp (acquired, name) != 0)
890 _dbus_warn ("Acquired name is %s but expected %s\n",
896 if (!check_no_leftovers (context))
902 dbus_error_free (&error);
905 dbus_free (acquired);
908 dbus_message_unref (message);
913 /* returns TRUE if the correct thing happens,
914 * but the correct thing may include OOM errors.
917 check_hello_connection (BusContext *context)
919 DBusConnection *connection;
922 dbus_error_init (&error);
924 connection = dbus_connection_open ("debug-pipe:name=test-server", &error);
925 if (connection == NULL)
927 _DBUS_ASSERT_ERROR_IS_SET (&error);
928 dbus_error_free (&error);
932 if (!bus_setup_debug_client (connection))
934 dbus_connection_disconnect (connection);
935 dbus_connection_unref (connection);
939 if (!check_hello_message (context, connection))
942 if (dbus_bus_get_base_service (connection) == NULL)
944 /* We didn't successfully register, so we can't
945 * do the usual kill_client_connection() checks
947 kill_client_connection_unchecked (connection);
951 kill_client_connection (context, connection);
957 #define NONEXISTENT_SERVICE_NAME "test.this.service.does.not.exist.ewuoiurjdfxcvn"
959 /* returns TRUE if the correct thing happens,
960 * but the correct thing may include OOM errors.
963 check_nonexistent_service_activation (BusContext *context,
964 DBusConnection *connection)
966 DBusMessage *message;
971 dbus_error_init (&error);
973 message = dbus_message_new (DBUS_SERVICE_DBUS,
974 DBUS_MESSAGE_ACTIVATE_SERVICE);
979 if (!dbus_message_append_args (message,
980 DBUS_TYPE_STRING, NONEXISTENT_SERVICE_NAME,
984 dbus_message_unref (message);
988 if (!dbus_connection_send (connection, message, &serial))
990 dbus_message_unref (message);
994 dbus_message_unref (message);
997 bus_test_run_everything (context);
998 block_connection_until_message_from_bus (context, connection);
999 bus_test_run_everything (context);
1001 if (!dbus_connection_get_is_connected (connection))
1003 _dbus_verbose ("connection was disconnected\n");
1009 message = pop_message_waiting_for_memory (connection);
1010 if (message == NULL)
1012 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1013 DBUS_MESSAGE_ACTIVATE_SERVICE, serial, connection);
1017 _dbus_verbose ("Received %s on %p\n",
1018 dbus_message_get_name (message), connection);
1020 if (dbus_message_get_is_error (message))
1022 if (!dbus_message_sender_is (message, DBUS_SERVICE_DBUS))
1024 _dbus_warn ("Message has wrong sender %s\n",
1025 dbus_message_get_sender (message) ?
1026 dbus_message_get_sender (message) : "(none)");
1030 if (dbus_message_name_is (message,
1031 DBUS_ERROR_NO_MEMORY))
1033 ; /* good, this is a valid response */
1035 else if (dbus_message_name_is (message,
1036 DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND))
1038 ; /* good, this is expected also */
1042 _dbus_warn ("Did not expect error %s\n",
1043 dbus_message_get_name (message));
1049 _dbus_warn ("Did not expect to successfully activate %s\n",
1050 NONEXISTENT_SERVICE_NAME);
1058 dbus_message_unref (message);
1064 check_base_service_activated (BusContext *context,
1065 DBusConnection *connection,
1066 DBusMessage *initial_message,
1067 char **base_service_p)
1069 DBusMessage *message;
1074 base_service = NULL;
1077 dbus_error_init (&error);
1079 message = initial_message;
1080 dbus_message_ref (message);
1082 if (dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_CREATED))
1085 CheckServiceCreatedData scd;
1087 reget_service_name_arg:
1088 if (!dbus_message_get_args (message, &error,
1089 DBUS_TYPE_STRING, &service_name,
1092 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1094 dbus_error_free (&error);
1095 _dbus_wait_for_memory ();
1096 goto reget_service_name_arg;
1100 _dbus_warn ("Message %s doesn't have a service name: %s\n",
1101 dbus_message_get_name (message),
1103 dbus_error_free (&error);
1108 if (*service_name != ':')
1110 _dbus_warn ("Expected base service activation, got \"%s\" instead\n",
1115 base_service = service_name;
1116 service_name = NULL;
1118 scd.skip_connection = connection;
1120 scd.expected_service_name = base_service;
1121 bus_test_clients_foreach (check_service_created_foreach,
1129 _dbus_warn ("Expected to get base service ServiceCreated, instead got %s\n",
1130 dbus_message_get_name (message));
1138 *base_service_p = base_service;
1139 base_service = NULL;
1144 dbus_message_unref (message);
1147 dbus_free (base_service);
1153 check_service_activated (BusContext *context,
1154 DBusConnection *connection,
1155 const char *activated_name,
1156 const char *base_service_name,
1157 DBusMessage *initial_message)
1159 DBusMessage *message;
1162 dbus_uint32_t activation_result;
1166 dbus_error_init (&error);
1168 message = initial_message;
1169 dbus_message_ref (message);
1171 if (dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_CREATED))
1174 CheckServiceCreatedData scd;
1176 reget_service_name_arg:
1177 if (!dbus_message_get_args (message, &error,
1178 DBUS_TYPE_STRING, &service_name,
1181 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1183 dbus_error_free (&error);
1184 _dbus_wait_for_memory ();
1185 goto reget_service_name_arg;
1189 _dbus_warn ("Message %s doesn't have a service name: %s\n",
1190 dbus_message_get_name (message),
1192 dbus_error_free (&error);
1197 if (strcmp (service_name, activated_name) != 0)
1199 _dbus_warn ("Expected to see service %s created, saw %s instead\n",
1200 activated_name, service_name);
1201 dbus_free (service_name);
1205 scd.skip_connection = connection;
1207 scd.expected_service_name = service_name;
1208 bus_test_clients_foreach (check_service_created_foreach,
1211 dbus_free (service_name);
1216 dbus_message_unref (message);
1217 message = pop_message_waiting_for_memory (connection);
1218 if (message == NULL)
1220 _dbus_warn ("Expected a reply to %s, got nothing\n",
1221 DBUS_MESSAGE_ACTIVATE_SERVICE);
1227 _dbus_warn ("Expected to get service %s ServiceCreated, instead got %s\n",
1228 activated_name, dbus_message_get_name (message));
1232 if (!dbus_message_name_is (message, DBUS_MESSAGE_ACTIVATE_SERVICE))
1234 _dbus_warn ("Expected reply to %s, got message %s instead\n",
1235 DBUS_MESSAGE_ACTIVATE_SERVICE,
1236 dbus_message_get_name (message));
1240 activation_result = 0;
1241 if (!dbus_message_get_args (message, &error,
1242 DBUS_TYPE_UINT32, &activation_result,
1245 if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1247 _dbus_warn ("Did not have activation result first argument to %s: %s\n",
1248 DBUS_MESSAGE_ACTIVATE_SERVICE, error.message);
1249 dbus_error_free (&error);
1253 dbus_error_free (&error);
1257 if (activation_result == DBUS_ACTIVATION_REPLY_ACTIVATED)
1259 else if (activation_result == DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE)
1263 _dbus_warn ("Activation result was 0x%x, no good.\n",
1269 dbus_message_unref (message);
1272 if (!check_no_leftovers (context))
1274 _dbus_warn ("Messages were left over after verifying existent activation results\n");
1282 dbus_message_unref (message);
1288 check_service_deactivated (BusContext *context,
1289 DBusConnection *connection,
1290 const char *activated_name,
1291 const char *base_service)
1293 DBusMessage *message;
1296 CheckServiceDeletedData csdd;
1301 dbus_error_init (&error);
1303 /* Now we are expecting ServiceDeleted messages for the base
1304 * service and the activated_name. The base service
1305 * notification is required to come last.
1307 csdd.expected_service_name = activated_name;
1308 csdd.failed = FALSE;
1309 bus_test_clients_foreach (check_service_deleted_foreach,
1315 csdd.expected_service_name = base_service;
1316 csdd.failed = FALSE;
1317 bus_test_clients_foreach (check_service_deleted_foreach,
1323 if (!check_no_leftovers (context))
1325 _dbus_warn ("Messages were left over after verifying results of service exiting\n");
1333 dbus_message_unref (message);
1339 check_send_exit_to_service (BusContext *context,
1340 DBusConnection *connection,
1341 const char *service_name,
1342 const char *base_service)
1344 dbus_bool_t got_error;
1345 DBusMessage *message;
1346 dbus_int32_t serial;
1349 _dbus_verbose ("Sending exit message to the test service\n");
1353 /* Kill off the test service by sending it a quit message */
1354 message = dbus_message_new (service_name,
1355 "org.freedesktop.DBus.TestSuiteExit");
1357 if (message == NULL)
1359 /* Do this again; we still need the service to exit... */
1360 if (!check_send_exit_to_service (context, connection,
1361 service_name, base_service))
1367 if (!dbus_connection_send (connection, message, &serial))
1369 dbus_message_unref (message);
1371 /* Do this again; we still need the service to exit... */
1372 if (!check_send_exit_to_service (context, connection,
1373 service_name, base_service))
1379 dbus_message_unref (message);
1383 bus_test_run_clients_loop (TRUE);
1385 /* read it in and write it out to test service */
1386 bus_test_run_bus_loop (context, FALSE);
1388 /* see if we got an error during message bus dispatching */
1389 bus_test_run_clients_loop (FALSE);
1390 message = dbus_connection_borrow_message (connection);
1391 got_error = message != NULL && dbus_message_get_is_error (message);
1393 dbus_connection_return_message (connection, message);
1397 /* If no error, wait for the test service to exit */
1398 block_connection_until_message_from_bus (context, connection);
1400 bus_test_run_everything (context);
1405 message = pop_message_waiting_for_memory (connection);
1406 _dbus_assert (message != NULL);
1408 if (!dbus_message_get_is_error (message))
1410 _dbus_warn ("expecting an error reply to asking test service to exit, got %s\n",
1411 dbus_message_get_name (message));
1414 else if (!dbus_message_name_is (message, DBUS_ERROR_NO_MEMORY))
1416 _dbus_warn ("not expecting error %s when asking test service to exit\n",
1417 dbus_message_get_name (message));
1421 _dbus_verbose ("Got error %s when asking test service to exit\n",
1422 dbus_message_get_name (message));
1424 /* Do this again; we still need the service to exit... */
1425 if (!check_send_exit_to_service (context, connection,
1426 service_name, base_service))
1431 if (!check_service_deactivated (context, connection,
1432 service_name, base_service))
1440 dbus_message_unref (message);
1445 #define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"
1447 /* returns TRUE if the correct thing happens,
1448 * but the correct thing may include OOM errors.
1451 check_existent_service_activation (BusContext *context,
1452 DBusConnection *connection)
1454 DBusMessage *message;
1455 dbus_int32_t serial;
1460 base_service = NULL;
1462 dbus_error_init (&error);
1464 message = dbus_message_new (DBUS_SERVICE_DBUS,
1465 DBUS_MESSAGE_ACTIVATE_SERVICE);
1467 if (message == NULL)
1470 if (!dbus_message_append_args (message,
1471 DBUS_TYPE_STRING, EXISTENT_SERVICE_NAME,
1472 DBUS_TYPE_UINT32, 0,
1475 dbus_message_unref (message);
1479 if (!dbus_connection_send (connection, message, &serial))
1481 dbus_message_unref (message);
1485 dbus_message_unref (message);
1488 bus_test_run_everything (context);
1490 /* now wait for the message bus to hear back from the activated
1493 block_connection_until_message_from_bus (context, connection);
1495 bus_test_run_everything (context);
1497 if (!dbus_connection_get_is_connected (connection))
1499 _dbus_verbose ("connection was disconnected\n");
1505 message = pop_message_waiting_for_memory (connection);
1506 if (message == NULL)
1508 _dbus_warn ("Did not receive any messages after %s %d on %p\n",
1509 DBUS_MESSAGE_ACTIVATE_SERVICE, serial, connection);
1513 _dbus_verbose ("Received %s on %p after sending %s\n",
1514 dbus_message_get_name (message), connection,
1515 DBUS_MESSAGE_ACTIVATE_SERVICE);
1517 if (dbus_message_get_is_error (message))
1519 if (!dbus_message_sender_is (message, DBUS_SERVICE_DBUS))
1521 _dbus_warn ("Message has wrong sender %s\n",
1522 dbus_message_get_sender (message) ?
1523 dbus_message_get_sender (message) : "(none)");
1527 if (dbus_message_name_is (message,
1528 DBUS_ERROR_NO_MEMORY))
1530 ; /* good, this is a valid response */
1532 else if (dbus_message_name_is (message,
1533 DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND))
1535 ; /* good, this is expected also */
1537 else if (dbus_message_name_is (message,
1538 DBUS_ERROR_SPAWN_CHILD_EXITED))
1540 ; /* good, this is expected also (child will exit if for example we don't
1541 * have memory to register it)
1546 _dbus_warn ("Did not expect error %s\n",
1547 dbus_message_get_name (message));
1553 dbus_bool_t got_service_deleted;
1555 if (!check_base_service_activated (context, connection,
1556 message, &base_service))
1559 dbus_message_unref (message);
1562 /* We may need to block here for the test service to exit or finish up */
1563 block_connection_until_message_from_bus (context, connection);
1565 message = dbus_connection_borrow_message (connection);
1566 if (message == NULL)
1568 _dbus_warn ("Did not receive any messages after base service creation notification\n");
1572 got_service_deleted = dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_DELETED);
1574 dbus_connection_return_message (connection, message);
1577 if (got_service_deleted)
1579 /* The service started up and got a base address, but then
1580 * failed to register under EXISTENT_SERVICE_NAME
1582 CheckServiceDeletedData csdd;
1584 csdd.expected_service_name = base_service;
1585 csdd.failed = FALSE;
1586 bus_test_clients_foreach (check_service_deleted_foreach,
1592 /* Now we should get an error about the service exiting */
1593 block_connection_until_message_from_bus (context, connection);
1595 /* and process everything again */
1596 bus_test_run_everything (context);
1598 message = pop_message_waiting_for_memory (connection);
1599 if (message == NULL)
1601 _dbus_warn ("Did not get an error from the service %s exiting\n",
1602 EXISTENT_SERVICE_NAME);
1606 if (!dbus_message_get_is_error (message))
1608 _dbus_warn ("Expected an error due to service exiting, got %s\n",
1609 dbus_message_get_name (message));
1613 if (!dbus_message_name_is (message,
1614 DBUS_ERROR_SPAWN_CHILD_EXITED))
1616 _dbus_warn ("Expected error %s on service exit, got %s instead\n",
1617 DBUS_ERROR_SPAWN_CHILD_EXITED,
1618 dbus_message_get_name (message));
1624 message = pop_message_waiting_for_memory (connection);
1625 if (message == NULL)
1627 _dbus_warn ("Failed to pop message we just put back! should have been a ServiceCreated\n");
1631 if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
1632 base_service, message))
1635 dbus_message_unref (message);
1639 if (!check_no_leftovers (context))
1641 _dbus_warn ("Messages were left over after successful activation\n");
1645 if (!check_send_exit_to_service (context, connection,
1646 EXISTENT_SERVICE_NAME, base_service))
1655 dbus_message_unref (message);
1658 dbus_free (base_service);
1666 BusContext *context;
1670 check_oom_check1_func (void *data)
1672 Check1Data *d = data;
1674 if (! (* d->func) (d->context))
1677 if (!check_no_leftovers (d->context))
1679 _dbus_warn ("Messages were left over, should be covered by test suite\n");
1687 check1_try_iterations (BusContext *context,
1688 const char *description,
1694 d.context = context;
1696 if (!_dbus_test_oom_handling (description, check_oom_check1_func,
1698 _dbus_assert_not_reached ("test failed");
1704 BusContext *context;
1705 DBusConnection *connection;
1709 check_oom_check2_func (void *data)
1711 Check2Data *d = data;
1713 if (! (* d->func) (d->context, d->connection))
1716 if (!check_no_leftovers (d->context))
1718 _dbus_warn ("Messages were left over, should be covered by test suite");
1726 check2_try_iterations (BusContext *context,
1727 DBusConnection *connection,
1728 const char *description,
1734 d.context = context;
1735 d.connection = connection;
1737 if (!_dbus_test_oom_handling (description, check_oom_check2_func,
1739 _dbus_assert_not_reached ("test failed");
1743 bus_dispatch_test (const DBusString *test_data_dir)
1745 BusContext *context;
1746 DBusConnection *foo;
1747 DBusConnection *bar;
1748 DBusConnection *baz;
1751 context = bus_context_new_test (test_data_dir,
1752 "valid-config-files/debug-allow-all.conf");
1753 if (context == NULL)
1756 dbus_error_init (&error);
1758 foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
1760 _dbus_assert_not_reached ("could not alloc connection");
1762 if (!bus_setup_debug_client (foo))
1763 _dbus_assert_not_reached ("could not set up connection");
1765 if (!check_hello_message (context, foo))
1766 _dbus_assert_not_reached ("hello message failed");
1768 bar = dbus_connection_open ("debug-pipe:name=test-server", &error);
1770 _dbus_assert_not_reached ("could not alloc connection");
1772 if (!bus_setup_debug_client (bar))
1773 _dbus_assert_not_reached ("could not set up connection");
1775 if (!check_hello_message (context, bar))
1776 _dbus_assert_not_reached ("hello message failed");
1778 baz = dbus_connection_open ("debug-pipe:name=test-server", &error);
1780 _dbus_assert_not_reached ("could not alloc connection");
1782 if (!bus_setup_debug_client (baz))
1783 _dbus_assert_not_reached ("could not set up connection");
1785 if (!check_hello_message (context, baz))
1786 _dbus_assert_not_reached ("hello message failed");
1789 check2_try_iterations (context, foo, "existent_service_activation",
1790 check_existent_service_activation);
1793 check2_try_iterations (context, foo, "nonexistent_service_activation",
1794 check_nonexistent_service_activation);
1796 check1_try_iterations (context, "create_and_hello",
1797 check_hello_connection);
1799 _dbus_verbose ("Disconnecting foo, bar, and baz\n");
1801 kill_client_connection_unchecked (foo);
1802 kill_client_connection_unchecked (bar);
1803 kill_client_connection_unchecked (baz);
1805 bus_context_unref (context);
1809 #endif /* DBUS_BUILD_TESTS */