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);
456 const char *expected_service_name;
458 } CheckServiceDeletedData;
461 check_service_deleted_foreach (DBusConnection *connection,
464 CheckServiceDeletedData *d = data;
465 DBusMessage *message;
469 dbus_error_init (&error);
473 message = dbus_connection_pop_message (connection);
476 _dbus_warn ("Did not receive a message on %p, expecting %s\n",
477 connection, DBUS_MESSAGE_SERVICE_DELETED);
480 else if (!dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_DELETED))
482 _dbus_warn ("Received message %s on %p, expecting %s\n",
483 dbus_message_get_name (message),
484 connection, DBUS_MESSAGE_SERVICE_DELETED);
489 if (!dbus_message_get_args (message, &error,
490 DBUS_TYPE_STRING, &service_name,
493 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
495 _dbus_verbose ("no memory to get service name arg\n");
499 _dbus_assert (dbus_error_is_set (&error));
500 _dbus_warn ("Did not get the expected single string argument\n");
504 else if (strcmp (service_name, d->expected_service_name) != 0)
506 _dbus_warn ("expected deletion of service %s, got deletion of %s\n",
507 d->expected_service_name,
516 dbus_free (service_name);
517 dbus_error_free (&error);
520 dbus_message_unref (message);
526 kill_client_connection (BusContext *context,
527 DBusConnection *connection)
531 CheckServiceDeletedData csdd;
533 _dbus_verbose ("killing connection %p\n", connection);
535 s = dbus_bus_get_base_service (connection);
536 _dbus_assert (s != NULL);
538 while ((base_service = _dbus_strdup (s)) == NULL)
539 _dbus_wait_for_memory ();
541 dbus_connection_ref (connection);
543 /* kick in the disconnect handler that unrefs the connection */
544 dbus_connection_disconnect (connection);
546 bus_test_run_everything (context);
548 _dbus_assert (bus_test_client_listed (connection));
550 /* Run disconnect handler in test.c */
551 if (bus_connection_dispatch_one_message (connection))
552 _dbus_assert_not_reached ("something received on connection being killed other than the disconnect");
554 _dbus_assert (!dbus_connection_get_is_connected (connection));
555 dbus_connection_unref (connection);
557 _dbus_assert (!bus_test_client_listed (connection));
559 csdd.expected_service_name = base_service;
562 bus_test_clients_foreach (check_service_deleted_foreach,
565 dbus_free (base_service);
568 _dbus_assert_not_reached ("didn't get the expected ServiceDeleted messages");
570 if (!check_no_leftovers (context))
571 _dbus_assert_not_reached ("stuff left in message queues after disconnecting a client");
575 kill_client_connection_unchecked (DBusConnection *connection)
577 /* This kills the connection without expecting it to affect
578 * the rest of the bus.
580 _dbus_verbose ("Unchecked kill of connection %p\n", connection);
582 dbus_connection_ref (connection);
583 dbus_connection_disconnect (connection);
584 /* dispatching disconnect handler will unref once */
585 if (bus_connection_dispatch_one_message (connection))
586 _dbus_assert_not_reached ("message other than disconnect dispatched after failure to register");
587 dbus_connection_unref (connection);
588 _dbus_assert (!bus_test_client_listed (connection));
594 } CheckNoMessagesData;
597 check_no_messages_foreach (DBusConnection *connection,
600 CheckNoMessagesData *d = data;
601 DBusMessage *message;
603 message = dbus_connection_pop_message (connection);
606 _dbus_warn ("Received message %s on %p, expecting no messages\n",
607 dbus_message_get_name (message), connection);
612 dbus_message_unref (message);
618 DBusConnection *skip_connection;
619 const char *expected_service_name;
621 } CheckServiceCreatedData;
624 check_service_created_foreach (DBusConnection *connection,
627 CheckServiceCreatedData *d = data;
628 DBusMessage *message;
632 if (connection == d->skip_connection)
635 dbus_error_init (&error);
639 message = dbus_connection_pop_message (connection);
642 _dbus_warn ("Did not receive a message on %p, expecting %s\n",
643 connection, DBUS_MESSAGE_SERVICE_CREATED);
646 else if (!dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_CREATED))
648 _dbus_warn ("Received message %s on %p, expecting %s\n",
649 dbus_message_get_name (message),
650 connection, DBUS_MESSAGE_SERVICE_CREATED);
655 if (!dbus_message_get_args (message, &error,
656 DBUS_TYPE_STRING, &service_name,
659 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
661 _dbus_verbose ("no memory to get service name arg\n");
665 _dbus_assert (dbus_error_is_set (&error));
666 _dbus_warn ("Did not get the expected single string argument\n");
670 else if (strcmp (service_name, d->expected_service_name) != 0)
672 _dbus_warn ("expected creation of service %s, got creation of %s\n",
673 d->expected_service_name,
682 dbus_free (service_name);
683 dbus_error_free (&error);
686 dbus_message_unref (message);
692 check_no_leftovers (BusContext *context)
694 CheckNoMessagesData nmd;
697 bus_test_clients_foreach (check_no_messages_foreach,
706 /* returns TRUE if the correct thing happens,
707 * but the correct thing may include OOM errors.
710 check_hello_message (BusContext *context,
711 DBusConnection *connection)
713 DBusMessage *message;
720 dbus_error_init (&error);
724 message = dbus_message_new (DBUS_SERVICE_DBUS,
730 if (!dbus_connection_send (connection, message, &serial))
732 dbus_message_unref (message);
736 dbus_message_unref (message);
739 bus_test_run_everything (context);
741 if (!dbus_connection_get_is_connected (connection))
743 _dbus_verbose ("connection was disconnected\n");
749 message = dbus_connection_pop_message (connection);
752 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
753 DBUS_MESSAGE_HELLO, serial, connection);
757 _dbus_verbose ("Received %s on %p\n",
758 dbus_message_get_name (message), connection);
760 if (!dbus_message_sender_is (message, DBUS_SERVICE_DBUS))
762 _dbus_warn ("Message has wrong sender %s\n",
763 dbus_message_get_sender (message) ?
764 dbus_message_get_sender (message) : "(none)");
768 if (dbus_message_get_is_error (message))
770 if (dbus_message_name_is (message,
771 DBUS_ERROR_NO_MEMORY))
773 ; /* good, this is a valid response */
777 _dbus_warn ("Did not expect error %s\n",
778 dbus_message_get_name (message));
784 CheckServiceCreatedData scd;
786 if (dbus_message_name_is (message,
789 ; /* good, expected */
793 _dbus_warn ("Did not expect reply %s\n",
794 dbus_message_get_name (message));
798 retry_get_hello_name:
799 if (!dbus_message_get_args (message, &error,
800 DBUS_TYPE_STRING, &name,
803 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
805 _dbus_verbose ("no memory to get service name arg from hello\n");
806 dbus_error_free (&error);
807 _dbus_wait_for_memory ();
808 goto retry_get_hello_name;
812 _dbus_assert (dbus_error_is_set (&error));
813 _dbus_warn ("Did not get the expected single string argument to hello\n");
818 _dbus_verbose ("Got hello name: %s\n", name);
820 while (!dbus_bus_set_base_service (connection, name))
821 _dbus_wait_for_memory ();
823 scd.skip_connection = NULL;
825 scd.expected_service_name = name;
826 bus_test_clients_foreach (check_service_created_foreach,
832 /* Client should also have gotten ServiceAcquired */
833 dbus_message_unref (message);
834 message = dbus_connection_pop_message (connection);
837 _dbus_warn ("Expecting %s, got nothing\n",
838 DBUS_MESSAGE_SERVICE_ACQUIRED);
842 retry_get_acquired_name:
843 if (!dbus_message_get_args (message, &error,
844 DBUS_TYPE_STRING, &acquired,
847 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
849 _dbus_verbose ("no memory to get service name arg from acquired\n");
850 dbus_error_free (&error);
851 _dbus_wait_for_memory ();
852 goto retry_get_acquired_name;
856 _dbus_assert (dbus_error_is_set (&error));
857 _dbus_warn ("Did not get the expected single string argument to ServiceAcquired\n");
862 _dbus_verbose ("Got acquired name: %s\n", acquired);
864 if (strcmp (acquired, name) != 0)
866 _dbus_warn ("Acquired name is %s but expected %s\n",
872 if (!check_no_leftovers (context))
878 dbus_error_free (&error);
881 dbus_free (acquired);
884 dbus_message_unref (message);
889 /* returns TRUE if the correct thing happens,
890 * but the correct thing may include OOM errors.
893 check_hello_connection (BusContext *context)
895 DBusConnection *connection;
898 dbus_error_init (&error);
900 connection = dbus_connection_open ("debug-pipe:name=test-server", &error);
901 if (connection == NULL)
903 _DBUS_ASSERT_ERROR_IS_SET (&error);
904 dbus_error_free (&error);
908 if (!bus_setup_debug_client (connection))
910 dbus_connection_disconnect (connection);
911 dbus_connection_unref (connection);
915 if (!check_hello_message (context, connection))
918 if (dbus_bus_get_base_service (connection) == NULL)
920 /* We didn't successfully register, so we can't
921 * do the usual kill_client_connection() checks
923 kill_client_connection_unchecked (connection);
927 kill_client_connection (context, connection);
933 #define NONEXISTENT_SERVICE_NAME "test.this.service.does.not.exist.ewuoiurjdfxcvn"
935 /* returns TRUE if the correct thing happens,
936 * but the correct thing may include OOM errors.
939 check_nonexistent_service_activation (BusContext *context,
940 DBusConnection *connection)
942 DBusMessage *message;
947 dbus_error_init (&error);
949 message = dbus_message_new (DBUS_SERVICE_DBUS,
950 DBUS_MESSAGE_ACTIVATE_SERVICE);
955 if (!dbus_message_append_args (message,
956 DBUS_TYPE_STRING, NONEXISTENT_SERVICE_NAME,
960 dbus_message_unref (message);
964 if (!dbus_connection_send (connection, message, &serial))
966 dbus_message_unref (message);
970 dbus_message_unref (message);
973 bus_test_run_everything (context);
975 if (!dbus_connection_get_is_connected (connection))
977 _dbus_verbose ("connection was disconnected\n");
983 message = dbus_connection_pop_message (connection);
986 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
987 DBUS_MESSAGE_ACTIVATE_SERVICE, serial, connection);
991 _dbus_verbose ("Received %s on %p\n",
992 dbus_message_get_name (message), connection);
994 if (dbus_message_get_is_error (message))
996 if (!dbus_message_sender_is (message, DBUS_SERVICE_DBUS))
998 _dbus_warn ("Message has wrong sender %s\n",
999 dbus_message_get_sender (message) ?
1000 dbus_message_get_sender (message) : "(none)");
1004 if (dbus_message_name_is (message,
1005 DBUS_ERROR_NO_MEMORY))
1007 ; /* good, this is a valid response */
1009 else if (dbus_message_name_is (message,
1010 DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND))
1012 ; /* good, this is expected also */
1016 _dbus_warn ("Did not expect error %s\n",
1017 dbus_message_get_name (message));
1023 _dbus_warn ("Did not expect to successfully activate %s\n",
1024 NONEXISTENT_SERVICE_NAME);
1032 dbus_message_unref (message);
1038 check_base_service_activated (BusContext *context,
1039 DBusConnection *connection,
1040 DBusMessage *initial_message,
1041 char **base_service_p)
1043 DBusMessage *message;
1048 base_service = NULL;
1051 dbus_error_init (&error);
1053 message = initial_message;
1054 dbus_message_ref (message);
1056 if (dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_CREATED))
1059 CheckServiceCreatedData scd;
1061 if (!dbus_message_get_args (message, &error,
1062 DBUS_TYPE_STRING, &service_name,
1065 _dbus_warn ("Message %s doesn't have a service name: %s\n",
1066 dbus_message_get_name (message),
1068 dbus_error_free (&error);
1072 if (*service_name != ':')
1074 _dbus_warn ("Expected base service activation, got \"%s\" instead\n",
1079 base_service = service_name;
1080 service_name = NULL;
1082 scd.skip_connection = connection;
1084 scd.expected_service_name = base_service;
1085 bus_test_clients_foreach (check_service_created_foreach,
1096 *base_service_p = base_service;
1097 base_service = NULL;
1102 dbus_message_unref (message);
1105 dbus_free (base_service);
1111 check_service_activated (BusContext *context,
1112 DBusConnection *connection,
1113 const char *activated_name,
1114 const char *base_service_name,
1115 DBusMessage *initial_message)
1117 DBusMessage *message;
1120 dbus_uint32_t activation_result;
1124 dbus_error_init (&error);
1126 message = initial_message;
1127 dbus_message_ref (message);
1129 if (dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_CREATED))
1132 CheckServiceCreatedData scd;
1134 if (!dbus_message_get_args (message, &error,
1135 DBUS_TYPE_STRING, &service_name,
1138 _dbus_warn ("Message %s doesn't have a service name: %s\n",
1139 dbus_message_get_name (message),
1141 dbus_error_free (&error);
1145 if (strcmp (service_name, activated_name) != 0)
1147 _dbus_warn ("Expected to see service %s created, saw %s instead\n",
1148 activated_name, service_name);
1149 dbus_free (service_name);
1153 scd.skip_connection = connection;
1155 scd.expected_service_name = service_name;
1156 bus_test_clients_foreach (check_service_created_foreach,
1159 dbus_free (service_name);
1164 dbus_message_unref (message);
1165 message = dbus_connection_pop_message (connection);
1166 if (message == NULL)
1168 _dbus_warn ("Expected a reply to %s, got nothing\n",
1169 DBUS_MESSAGE_ACTIVATE_SERVICE);
1174 if (!dbus_message_name_is (message, DBUS_MESSAGE_ACTIVATE_SERVICE))
1176 _dbus_warn ("Expected reply to %s, got message %s instead\n",
1177 DBUS_MESSAGE_ACTIVATE_SERVICE,
1178 dbus_message_get_name (message));
1182 activation_result = 0;
1183 if (!dbus_message_get_args (message, &error,
1184 DBUS_TYPE_UINT32, &activation_result,
1187 if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1189 _dbus_warn ("Did not have activation result first argument to %s: %s\n",
1190 DBUS_MESSAGE_ACTIVATE_SERVICE, error.message);
1191 dbus_error_free (&error);
1195 dbus_error_free (&error);
1199 if (activation_result == DBUS_ACTIVATION_REPLY_ACTIVATED)
1201 else if (activation_result == DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE)
1205 _dbus_warn ("Activation result was 0x%x, no good.\n",
1211 dbus_message_unref (message);
1214 if (!check_no_leftovers (context))
1216 _dbus_warn ("Messages were left over after verifying existent activation results\n");
1224 dbus_message_unref (message);
1230 check_service_deactivated (BusContext *context,
1231 DBusConnection *connection,
1232 const char *activated_name,
1233 const char *base_service)
1235 DBusMessage *message;
1238 CheckServiceDeletedData csdd;
1243 dbus_error_init (&error);
1245 /* Now we are expecting ServiceDeleted messages for the base
1246 * service and the activated_name. The base service
1247 * notification is required to come last.
1249 csdd.expected_service_name = activated_name;
1250 csdd.failed = FALSE;
1251 bus_test_clients_foreach (check_service_deleted_foreach,
1257 csdd.expected_service_name = base_service;
1258 csdd.failed = FALSE;
1259 bus_test_clients_foreach (check_service_deleted_foreach,
1265 if (!check_no_leftovers (context))
1267 _dbus_warn ("Messages were left over after verifying results of service exiting\n");
1275 dbus_message_unref (message);
1280 #define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"
1282 /* returns TRUE if the correct thing happens,
1283 * but the correct thing may include OOM errors.
1286 check_existent_service_activation (BusContext *context,
1287 DBusConnection *connection)
1289 DBusMessage *message;
1290 dbus_int32_t serial;
1295 base_service = NULL;
1297 dbus_error_init (&error);
1299 message = dbus_message_new (DBUS_SERVICE_DBUS,
1300 DBUS_MESSAGE_ACTIVATE_SERVICE);
1302 if (message == NULL)
1305 if (!dbus_message_append_args (message,
1306 DBUS_TYPE_STRING, EXISTENT_SERVICE_NAME,
1307 DBUS_TYPE_UINT32, 0,
1310 dbus_message_unref (message);
1314 if (!dbus_connection_send (connection, message, &serial))
1316 dbus_message_unref (message);
1320 dbus_message_unref (message);
1323 bus_test_run_everything (context);
1325 if (dbus_connection_get_dispatch_status (connection) ==
1326 DBUS_DISPATCH_COMPLETE)
1327 /* now wait for the message bus to hear back from the activated service */
1328 bus_test_run_bus_loop (context, TRUE);
1330 /* and process everything again */
1331 bus_test_run_everything (context);
1333 if (!dbus_connection_get_is_connected (connection))
1335 _dbus_verbose ("connection was disconnected\n");
1341 message = dbus_connection_pop_message (connection);
1342 if (message == NULL)
1344 _dbus_warn ("Did not receive any messages after %s %d on %p\n",
1345 DBUS_MESSAGE_ACTIVATE_SERVICE, serial, connection);
1349 _dbus_verbose ("Received %s on %p\n",
1350 dbus_message_get_name (message), connection);
1352 if (dbus_message_get_is_error (message))
1354 if (!dbus_message_sender_is (message, DBUS_SERVICE_DBUS))
1356 _dbus_warn ("Message has wrong sender %s\n",
1357 dbus_message_get_sender (message) ?
1358 dbus_message_get_sender (message) : "(none)");
1362 if (dbus_message_name_is (message,
1363 DBUS_ERROR_NO_MEMORY))
1365 ; /* good, this is a valid response */
1367 else if (dbus_message_name_is (message,
1368 DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND))
1370 ; /* good, this is expected also */
1372 else if (dbus_message_name_is (message,
1373 DBUS_ERROR_SPAWN_CHILD_EXITED))
1375 ; /* good, this is expected also (child will exit if for example we don't
1376 * have memory to register it)
1381 _dbus_warn ("Did not expect error %s\n",
1382 dbus_message_get_name (message));
1388 dbus_bool_t got_service_deleted;
1390 if (!check_base_service_activated (context, connection,
1391 message, &base_service))
1394 dbus_message_unref (message);
1397 /* We may need to block here for the test service to exit or finish up */
1398 if (dbus_connection_get_dispatch_status (connection) ==
1399 DBUS_DISPATCH_COMPLETE)
1400 bus_test_run_bus_loop (context, TRUE);
1402 message = dbus_connection_borrow_message (connection);
1403 if (message == NULL)
1405 _dbus_warn ("Did not receive any messages after base service creation notification\n");
1409 got_service_deleted = dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_DELETED);
1411 dbus_connection_return_message (connection, message);
1414 if (got_service_deleted)
1416 /* The service started up and got a base address, but then
1417 * failed to register under EXISTENT_SERVICE_NAME
1419 CheckServiceDeletedData csdd;
1421 csdd.expected_service_name = base_service;
1422 csdd.failed = FALSE;
1423 bus_test_clients_foreach (check_service_deleted_foreach,
1429 /* Now we should get an error about the service exiting */
1430 if (dbus_connection_get_dispatch_status (connection) ==
1431 DBUS_DISPATCH_COMPLETE)
1432 /* wait for the message bus to hear back from the activated service exiting */
1433 bus_test_run_bus_loop (context, TRUE);
1435 /* and process everything again */
1436 bus_test_run_everything (context);
1438 message = dbus_connection_pop_message (connection);
1439 if (message == NULL)
1441 _dbus_warn ("Did not get an error from the service %s exiting\n",
1442 EXISTENT_SERVICE_NAME);
1446 if (!dbus_message_get_is_error (message))
1448 _dbus_warn ("Expected an error due to service exiting, got %s\n",
1449 dbus_message_get_name (message));
1453 if (!dbus_message_name_is (message,
1454 DBUS_ERROR_SPAWN_CHILD_EXITED))
1456 _dbus_warn ("Expected error %s on service exit, got %s instead\n",
1457 DBUS_ERROR_SPAWN_CHILD_EXITED,
1458 dbus_message_get_name (message));
1464 dbus_bool_t got_error;
1466 message = dbus_connection_pop_message (connection);
1467 if (message == NULL)
1469 _dbus_warn ("Failed to pop message we just put back! should have been a ServiceCreated\n");
1473 if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
1474 base_service, message))
1477 dbus_message_unref (message);
1481 if (!check_no_leftovers (context))
1483 _dbus_warn ("Messages were left over after successful activation\n");
1487 /* Now kill off the test service by sending it a quit message */
1488 message = dbus_message_new (EXISTENT_SERVICE_NAME,
1489 "org.freedesktop.DBus.TestSuiteExit");
1491 if (message == NULL)
1493 dbus_free (base_service);
1497 if (!dbus_connection_send (connection, message, &serial))
1499 dbus_message_unref (message);
1500 dbus_free (base_service);
1504 dbus_message_unref (message);
1508 bus_test_run_clients_loop (TRUE);
1510 /* read it in and write it out to test service */
1511 bus_test_run_bus_loop (context, FALSE);
1513 /* see if we got an error */
1514 bus_test_run_clients_loop (FALSE);
1515 message = dbus_connection_borrow_message (connection);
1516 got_error = message != NULL && dbus_message_get_is_error (message);
1518 dbus_connection_return_message (connection, message);
1522 if (dbus_connection_get_dispatch_status (connection) == DBUS_DISPATCH_COMPLETE)
1523 /* now wait for the message bus to hear back from the activated service exiting */
1524 bus_test_run_bus_loop (context, TRUE);
1526 /* and process everything again */
1527 bus_test_run_everything (context);
1532 message = dbus_connection_pop_message (connection);
1533 _dbus_assert (message != NULL);
1535 if (!dbus_message_get_is_error (message))
1537 _dbus_warn ("expecting an error reply to asking test service to exit, got %s\n",
1538 dbus_message_get_name (message));
1541 else if (!dbus_message_name_is (message, DBUS_ERROR_NO_MEMORY))
1543 _dbus_warn ("not expecting error %s when asking test service to exit\n",
1544 dbus_message_get_name (message));
1550 if (!check_service_deactivated (context, connection,
1551 EXISTENT_SERVICE_NAME, base_service))
1561 dbus_message_unref (message);
1564 dbus_free (base_service);
1572 BusContext *context;
1576 check_oom_check1_func (void *data)
1578 Check1Data *d = data;
1580 if (! (* d->func) (d->context))
1583 if (!check_no_leftovers (d->context))
1585 _dbus_warn ("Messages were left over, should be covered by test suite\n");
1593 check1_try_iterations (BusContext *context,
1594 const char *description,
1600 d.context = context;
1602 if (!_dbus_test_oom_handling (description, check_oom_check1_func,
1604 _dbus_assert_not_reached ("test failed");
1610 BusContext *context;
1611 DBusConnection *connection;
1615 check_oom_check2_func (void *data)
1617 Check2Data *d = data;
1619 if (! (* d->func) (d->context, d->connection))
1622 if (!check_no_leftovers (d->context))
1624 _dbus_warn ("Messages were left over, should be covered by test suite");
1632 check2_try_iterations (BusContext *context,
1633 DBusConnection *connection,
1634 const char *description,
1640 d.context = context;
1641 d.connection = connection;
1643 if (!_dbus_test_oom_handling (description, check_oom_check2_func,
1645 _dbus_assert_not_reached ("test failed");
1649 bus_dispatch_test (const DBusString *test_data_dir)
1651 BusContext *context;
1652 DBusConnection *foo;
1653 DBusConnection *bar;
1654 DBusConnection *baz;
1657 context = bus_context_new_test (test_data_dir,
1658 "valid-config-files/debug-allow-all.conf");
1659 if (context == NULL)
1662 dbus_error_init (&error);
1664 foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
1666 _dbus_assert_not_reached ("could not alloc connection");
1668 if (!bus_setup_debug_client (foo))
1669 _dbus_assert_not_reached ("could not set up connection");
1671 if (!check_hello_message (context, foo))
1672 _dbus_assert_not_reached ("hello message failed");
1674 bar = dbus_connection_open ("debug-pipe:name=test-server", &error);
1676 _dbus_assert_not_reached ("could not alloc connection");
1678 if (!bus_setup_debug_client (bar))
1679 _dbus_assert_not_reached ("could not set up connection");
1681 if (!check_hello_message (context, bar))
1682 _dbus_assert_not_reached ("hello message failed");
1684 baz = dbus_connection_open ("debug-pipe:name=test-server", &error);
1686 _dbus_assert_not_reached ("could not alloc connection");
1688 if (!bus_setup_debug_client (baz))
1689 _dbus_assert_not_reached ("could not set up connection");
1691 if (!check_hello_message (context, baz))
1692 _dbus_assert_not_reached ("hello message failed");
1695 check2_try_iterations (context, foo, "existent_service_activation",
1696 check_existent_service_activation);
1699 check2_try_iterations (context, foo, "nonexistent_service_activation",
1700 check_nonexistent_service_activation);
1702 check1_try_iterations (context, "create_and_hello",
1703 check_hello_connection);
1705 _dbus_verbose ("Disconnecting foo, bar, and baz\n");
1707 kill_client_connection_unchecked (foo);
1708 kill_client_connection_unchecked (bar);
1709 kill_client_connection_unchecked (baz);
1711 bus_context_unref (context);
1715 #endif /* DBUS_BUILD_TESTS */