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_service_activated (BusContext *context,
1039 DBusConnection *connection,
1040 const char *activated_name,
1041 dbus_bool_t require_base_service,
1042 DBusMessage *initial_message,
1043 char **base_service_p)
1045 DBusMessage *message;
1049 dbus_uint32_t activation_result;
1050 dbus_bool_t already_saw_base_created;
1052 base_service = NULL;
1055 dbus_error_init (&error);
1057 message = initial_message;
1058 dbus_message_ref (message);
1060 /* This is kind of a mess since we get the creation of
1061 * the base service only if the activated service didn't
1062 * already exist. Right now the test kills and restarts
1063 * the service each time, so the mess is pointless.
1065 already_saw_base_created = FALSE;
1067 recheck_service_created:
1068 if (dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_CREATED))
1071 CheckServiceCreatedData scd;
1073 if (!dbus_message_get_args (message, &error,
1074 DBUS_TYPE_STRING, &service_name,
1077 _dbus_warn ("Message %s doesn't have a service name: %s\n",
1078 dbus_message_get_name (message),
1080 dbus_error_free (&error);
1084 if (!already_saw_base_created && *service_name == ':')
1086 /* This is a base service name, mop up all the
1087 * other messages about it
1090 base_service = service_name;
1091 service_name = NULL;
1093 scd.skip_connection = connection;
1095 scd.expected_service_name = base_service;
1096 bus_test_clients_foreach (check_service_created_foreach,
1102 already_saw_base_created = TRUE;
1104 dbus_message_unref (message);
1105 message = dbus_connection_pop_message (connection);
1106 if (message == NULL)
1108 _dbus_warn ("Expected a ServiceCreated for the activated service, got nothing\n");
1112 goto recheck_service_created;
1114 else if (require_base_service && !already_saw_base_created)
1116 _dbus_warn ("Did not get a ServiceCreated for a base service, it was for %s instead\n",
1121 if (strcmp (service_name, activated_name) != 0)
1123 _dbus_warn ("Expected to see service %s created, saw %s instead\n",
1124 activated_name, service_name);
1125 dbus_free (service_name);
1129 scd.skip_connection = connection;
1131 scd.expected_service_name = service_name;
1132 bus_test_clients_foreach (check_service_created_foreach,
1135 dbus_free (service_name);
1140 dbus_message_unref (message);
1141 message = dbus_connection_pop_message (connection);
1142 if (message == NULL)
1144 _dbus_warn ("Expected a reply to %s, got nothing\n",
1145 DBUS_MESSAGE_ACTIVATE_SERVICE);
1150 if (!dbus_message_name_is (message, DBUS_MESSAGE_ACTIVATE_SERVICE))
1152 _dbus_warn ("Expected reply to %s, got message %s instead\n",
1153 DBUS_MESSAGE_ACTIVATE_SERVICE,
1154 dbus_message_get_name (message));
1158 activation_result = 0;
1159 if (!dbus_message_get_args (message, &error,
1160 DBUS_TYPE_UINT32, &activation_result,
1163 if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1165 _dbus_warn ("Did not have activation result first argument to %s: %s\n",
1166 DBUS_MESSAGE_ACTIVATE_SERVICE, error.message);
1167 dbus_error_free (&error);
1171 dbus_error_free (&error);
1175 if (activation_result == DBUS_ACTIVATION_REPLY_ACTIVATED)
1177 else if (activation_result == DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE)
1181 _dbus_warn ("Activation result was 0x%x, no good.\n",
1187 dbus_message_unref (message);
1190 if (!check_no_leftovers (context))
1192 _dbus_warn ("Messages were left over after verifying existent activation results\n");
1200 *base_service_p = base_service;
1201 base_service = NULL;
1206 dbus_message_unref (message);
1209 dbus_free (base_service);
1215 check_service_deactivated (BusContext *context,
1216 DBusConnection *connection,
1217 const char *activated_name,
1218 const char *base_service)
1220 DBusMessage *message;
1223 CheckServiceDeletedData csdd;
1228 dbus_error_init (&error);
1230 /* Now we are expecting ServiceDeleted messages for the base
1231 * service and the activated_name. The base service
1232 * notification is required to come last.
1234 csdd.expected_service_name = activated_name;
1235 csdd.failed = FALSE;
1236 bus_test_clients_foreach (check_service_deleted_foreach,
1242 csdd.expected_service_name = base_service;
1243 csdd.failed = FALSE;
1244 bus_test_clients_foreach (check_service_deleted_foreach,
1250 if (!check_no_leftovers (context))
1252 _dbus_warn ("Messages were left over after verifying results of service exiting\n");
1260 dbus_message_unref (message);
1265 #define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"
1267 /* returns TRUE if the correct thing happens,
1268 * but the correct thing may include OOM errors.
1271 check_existent_service_activation (BusContext *context,
1272 DBusConnection *connection)
1274 DBusMessage *message;
1275 dbus_int32_t serial;
1280 base_service = NULL;
1282 dbus_error_init (&error);
1284 message = dbus_message_new (DBUS_SERVICE_DBUS,
1285 DBUS_MESSAGE_ACTIVATE_SERVICE);
1287 if (message == NULL)
1290 if (!dbus_message_append_args (message,
1291 DBUS_TYPE_STRING, EXISTENT_SERVICE_NAME,
1292 DBUS_TYPE_UINT32, 0,
1295 dbus_message_unref (message);
1299 if (!dbus_connection_send (connection, message, &serial))
1301 dbus_message_unref (message);
1305 dbus_message_unref (message);
1308 bus_test_run_everything (context);
1310 if (dbus_connection_get_dispatch_status (connection) ==
1311 DBUS_DISPATCH_COMPLETE)
1312 /* now wait for the message bus to hear back from the activated service */
1313 bus_test_run_bus_loop (context, TRUE);
1315 /* and process everything again */
1316 bus_test_run_everything (context);
1318 if (!dbus_connection_get_is_connected (connection))
1320 _dbus_verbose ("connection was disconnected\n");
1326 message = dbus_connection_pop_message (connection);
1327 if (message == NULL)
1329 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1330 DBUS_MESSAGE_ACTIVATE_SERVICE, serial, connection);
1334 _dbus_verbose ("Received %s on %p\n",
1335 dbus_message_get_name (message), connection);
1337 if (dbus_message_get_is_error (message))
1339 if (!dbus_message_sender_is (message, DBUS_SERVICE_DBUS))
1341 _dbus_warn ("Message has wrong sender %s\n",
1342 dbus_message_get_sender (message) ?
1343 dbus_message_get_sender (message) : "(none)");
1347 if (dbus_message_name_is (message,
1348 DBUS_ERROR_NO_MEMORY))
1350 ; /* good, this is a valid response */
1352 else if (dbus_message_name_is (message,
1353 DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND))
1355 ; /* good, this is expected also */
1357 else if (dbus_message_name_is (message,
1358 DBUS_ERROR_SPAWN_CHILD_EXITED))
1360 ; /* good, this is expected also (child will exit if for example we don't
1361 * have memory to register it)
1366 _dbus_warn ("Did not expect error %s\n",
1367 dbus_message_get_name (message));
1373 if (!check_service_activated (context, connection,
1374 EXISTENT_SERVICE_NAME, TRUE,
1375 message, &base_service))
1378 dbus_message_unref (message);
1381 /* Now kill off the test service by sending it a quit message */
1382 message = dbus_message_new (EXISTENT_SERVICE_NAME,
1383 "org.freedesktop.DBus.TestSuiteExit");
1385 if (message == NULL)
1387 dbus_free (base_service);
1391 if (!dbus_connection_send (connection, message, &serial))
1393 dbus_message_unref (message);
1394 dbus_free (base_service);
1398 dbus_message_unref (message);
1402 bus_test_run_clients_loop (TRUE);
1404 /* read it in and write it out to test service */
1405 bus_test_run_bus_loop (context, FALSE);
1407 if (dbus_connection_get_dispatch_status (connection) ==
1408 DBUS_DISPATCH_COMPLETE)
1409 /* now wait for the message bus to hear back from the activated service exiting */
1410 bus_test_run_bus_loop (context, TRUE);
1412 /* and process everything again */
1413 bus_test_run_everything (context);
1415 if (!check_service_deactivated (context, connection,
1416 EXISTENT_SERVICE_NAME, base_service))
1424 dbus_message_unref (message);
1427 dbus_free (base_service);
1435 BusContext *context;
1439 check_oom_check1_func (void *data)
1441 Check1Data *d = data;
1443 if (! (* d->func) (d->context))
1446 if (!check_no_leftovers (d->context))
1448 _dbus_warn ("Messages were left over, should be covered by test suite\n");
1456 check1_try_iterations (BusContext *context,
1457 const char *description,
1463 d.context = context;
1465 if (!_dbus_test_oom_handling (description, check_oom_check1_func,
1467 _dbus_assert_not_reached ("test failed");
1473 BusContext *context;
1474 DBusConnection *connection;
1478 check_oom_check2_func (void *data)
1480 Check2Data *d = data;
1482 if (! (* d->func) (d->context, d->connection))
1485 if (!check_no_leftovers (d->context))
1487 _dbus_warn ("Messages were left over, should be covered by test suite");
1495 check2_try_iterations (BusContext *context,
1496 DBusConnection *connection,
1497 const char *description,
1503 d.context = context;
1504 d.connection = connection;
1506 if (!_dbus_test_oom_handling (description, check_oom_check2_func,
1508 _dbus_assert_not_reached ("test failed");
1512 bus_dispatch_test (const DBusString *test_data_dir)
1514 BusContext *context;
1515 DBusConnection *foo;
1516 DBusConnection *bar;
1517 DBusConnection *baz;
1520 context = bus_context_new_test (test_data_dir,
1521 "valid-config-files/debug-allow-all.conf");
1522 if (context == NULL)
1525 dbus_error_init (&error);
1527 foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
1529 _dbus_assert_not_reached ("could not alloc connection");
1531 if (!bus_setup_debug_client (foo))
1532 _dbus_assert_not_reached ("could not set up connection");
1534 if (!check_hello_message (context, foo))
1535 _dbus_assert_not_reached ("hello message failed");
1537 bar = dbus_connection_open ("debug-pipe:name=test-server", &error);
1539 _dbus_assert_not_reached ("could not alloc connection");
1541 if (!bus_setup_debug_client (bar))
1542 _dbus_assert_not_reached ("could not set up connection");
1544 if (!check_hello_message (context, bar))
1545 _dbus_assert_not_reached ("hello message failed");
1547 baz = dbus_connection_open ("debug-pipe:name=test-server", &error);
1549 _dbus_assert_not_reached ("could not alloc connection");
1551 if (!bus_setup_debug_client (baz))
1552 _dbus_assert_not_reached ("could not set up connection");
1554 if (!check_hello_message (context, baz))
1555 _dbus_assert_not_reached ("hello message failed");
1558 check2_try_iterations (context, foo, "existent_service_activation",
1559 check_existent_service_activation);
1562 check2_try_iterations (context, foo, "nonexistent_service_activation",
1563 check_nonexistent_service_activation);
1565 check1_try_iterations (context, "create_and_hello",
1566 check_hello_connection);
1568 _dbus_verbose ("Disconnecting foo, bar, and baz\n");
1570 kill_client_connection_unchecked (foo);
1571 kill_client_connection_unchecked (bar);
1572 kill_client_connection_unchecked (baz);
1574 bus_context_unref (context);
1578 #endif /* DBUS_BUILD_TESTS */