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.
6 * Copyright (C) 2004 Imendio HB
8 * Licensed under the Academic Free License version 2.1
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "connection.h"
30 #include "activation.h"
35 #include <dbus/dbus-internals.h>
39 send_one_message (DBusConnection *connection,
41 DBusConnection *sender,
42 DBusConnection *addressed_recipient,
44 BusTransaction *transaction,
47 if (!bus_context_check_security_policy (context, transaction,
53 return TRUE; /* silently don't send it */
55 if (!bus_transaction_send (transaction,
67 bus_dispatch_matches (BusTransaction *transaction,
68 DBusConnection *sender,
69 DBusConnection *addressed_recipient,
74 BusConnections *connections;
76 BusMatchmaker *matchmaker;
80 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
82 /* sender and recipient can both be NULL for the bus driver,
83 * or for signals with no particular recipient
86 _dbus_assert (sender == NULL || bus_connection_is_active (sender));
87 _dbus_assert (dbus_message_get_sender (message) != NULL);
89 connections = bus_transaction_get_connections (transaction);
91 dbus_error_init (&tmp_error);
92 context = bus_transaction_get_context (transaction);
93 matchmaker = bus_context_get_matchmaker (context);
96 if (!bus_matchmaker_get_recipients (matchmaker, connections,
97 sender, addressed_recipient, message,
104 link = _dbus_list_get_first_link (&recipients);
107 DBusConnection *dest;
111 if (!send_one_message (dest, context, sender, addressed_recipient,
112 message, transaction, &tmp_error))
115 link = _dbus_list_get_next_link (&recipients, link);
118 _dbus_list_clear (&recipients);
120 if (dbus_error_is_set (&tmp_error))
122 dbus_move_error (&tmp_error, error);
129 static DBusHandlerResult
130 bus_dispatch (DBusConnection *connection,
131 DBusMessage *message)
133 const char *sender, *service_name;
135 BusTransaction *transaction;
137 DBusHandlerResult result;
138 DBusConnection *addressed_recipient;
140 result = DBUS_HANDLER_RESULT_HANDLED;
143 addressed_recipient = NULL;
144 dbus_error_init (&error);
146 context = bus_connection_get_context (connection);
147 _dbus_assert (context != NULL);
149 /* If we can't even allocate an OOM error, we just go to sleep
152 while (!bus_connection_preallocate_oom_error (connection))
153 _dbus_wait_for_memory ();
155 /* Ref connection in case we disconnect it at some point in here */
156 dbus_connection_ref (connection);
158 service_name = dbus_message_get_destination (message);
160 #ifdef DBUS_ENABLE_VERBOSE_MODE
162 const char *interface_name, *member_name, *error_name;
164 interface_name = dbus_message_get_interface (message);
165 member_name = dbus_message_get_member (message);
166 error_name = dbus_message_get_error_name (message);
168 _dbus_verbose ("DISPATCH: %s %s %s to %s\n",
169 interface_name ? interface_name : "(no interface)",
170 member_name ? member_name : "(no member)",
171 error_name ? error_name : "(no error name)",
172 service_name ? service_name : "peer");
174 #endif /* DBUS_ENABLE_VERBOSE_MODE */
176 /* If service_name is NULL, if it's a signal we send it to all
177 * connections with a match rule. If it's not a signal, there
178 * are some special cases here but mostly we just bail out.
180 if (service_name == NULL)
182 if (dbus_message_is_signal (message,
183 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
186 bus_connection_disconnected (connection);
190 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL)
192 /* DBusConnection also handles some of these automatically, we leave
195 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
200 /* Create our transaction */
201 transaction = bus_transaction_new (context);
202 if (transaction == NULL)
204 BUS_SET_OOM (&error);
208 /* Assign a sender to the message */
209 if (bus_connection_is_active (connection))
211 sender = bus_connection_get_name (connection);
212 _dbus_assert (sender != NULL);
214 if (!dbus_message_set_sender (message, sender))
216 BUS_SET_OOM (&error);
220 /* We need to refetch the service name here, because
221 * dbus_message_set_sender can cause the header to be
222 * reallocated, and thus the service_name pointer will become
225 service_name = dbus_message_get_destination (message);
229 strcmp (service_name, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS) == 0) /* to bus driver */
231 if (!bus_context_check_security_policy (context, transaction,
232 connection, NULL, NULL, message, &error))
234 _dbus_verbose ("Security policy rejected message\n");
238 _dbus_verbose ("Giving message to %s\n", DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
239 if (!bus_driver_handle_message (connection, transaction, message, &error))
242 else if (!bus_connection_is_active (connection)) /* clients must talk to bus driver first */
244 _dbus_verbose ("Received message from non-registered client. Disconnecting.\n");
245 dbus_connection_disconnect (connection);
248 else if (service_name != NULL) /* route to named service */
250 DBusString service_string;
252 BusRegistry *registry;
254 _dbus_assert (service_name != NULL);
256 registry = bus_connection_get_registry (connection);
258 _dbus_string_init_const (&service_string, service_name);
259 service = bus_registry_lookup (registry, &service_string);
261 if (service == NULL && dbus_message_get_auto_activation (message))
263 BusActivation *activation;
265 /* We can't do the security policy check here, since the addressed
266 * recipient service doesn't exist yet. We do it before sending the
267 * message after the service has been created.
269 activation = bus_connection_get_activation (connection);
271 if (!bus_activation_activate_service (activation, connection, transaction, TRUE,
272 message, service_name, &error))
274 _DBUS_ASSERT_ERROR_IS_SET (&error);
275 _dbus_verbose ("bus_activation_activate_service() failed\n");
281 else if (service == NULL)
283 dbus_set_error (&error,
284 DBUS_ERROR_SERVICE_DOES_NOT_EXIST,
285 "Service \"%s\" does not exist",
291 addressed_recipient = bus_service_get_primary_owner (service);
292 _dbus_assert (addressed_recipient != NULL);
294 if (!bus_context_check_security_policy (context, transaction,
295 connection, addressed_recipient,
300 /* Dispatch the message */
301 if (!bus_transaction_send (transaction, addressed_recipient, message))
303 BUS_SET_OOM (&error);
309 /* Now match the messages against any match rules, which will send
310 * out signals and such. addressed_recipient may == NULL.
312 if (!bus_dispatch_matches (transaction, connection, addressed_recipient, message, &error))
316 if (dbus_error_is_set (&error))
318 if (!dbus_connection_get_is_connected (connection))
320 /* If we disconnected it, we won't bother to send it any error
323 _dbus_verbose ("Not sending error to connection we disconnected\n");
325 else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
327 bus_connection_send_oom_error (connection, message);
329 /* cancel transaction due to OOM */
330 if (transaction != NULL)
332 bus_transaction_cancel_and_free (transaction);
338 /* Try to send the real error, if no mem to do that, send
341 _dbus_assert (transaction != NULL);
343 if (!bus_transaction_send_error_reply (transaction, connection,
346 bus_connection_send_oom_error (connection, message);
348 /* cancel transaction due to OOM */
349 if (transaction != NULL)
351 bus_transaction_cancel_and_free (transaction);
357 dbus_error_free (&error);
360 if (transaction != NULL)
362 bus_transaction_execute_and_free (transaction);
365 dbus_connection_unref (connection);
370 static DBusHandlerResult
371 bus_dispatch_message_filter (DBusConnection *connection,
372 DBusMessage *message,
375 return bus_dispatch (connection, message);
379 bus_dispatch_add_connection (DBusConnection *connection)
381 if (!dbus_connection_add_filter (connection,
382 bus_dispatch_message_filter,
390 bus_dispatch_remove_connection (DBusConnection *connection)
392 /* Here we tell the bus driver that we want to get off. */
393 bus_driver_remove_connection (connection);
395 dbus_connection_remove_filter (connection,
396 bus_dispatch_message_filter,
400 #ifdef DBUS_BUILD_TESTS
404 typedef dbus_bool_t (* Check1Func) (BusContext *context);
405 typedef dbus_bool_t (* Check2Func) (BusContext *context,
406 DBusConnection *connection);
408 static dbus_bool_t check_no_leftovers (BusContext *context);
411 block_connection_until_message_from_bus (BusContext *context,
412 DBusConnection *connection)
414 while (dbus_connection_get_dispatch_status (connection) ==
415 DBUS_DISPATCH_COMPLETE &&
416 dbus_connection_get_is_connected (connection))
418 bus_test_run_bus_loop (context, TRUE);
419 bus_test_run_clients_loop (FALSE);
423 /* compensate for fact that pop_message() can return #NULL due to OOM */
425 pop_message_waiting_for_memory (DBusConnection *connection)
427 while (dbus_connection_get_dispatch_status (connection) ==
428 DBUS_DISPATCH_NEED_MEMORY)
429 _dbus_wait_for_memory ();
431 return dbus_connection_pop_message (connection);
435 borrow_message_waiting_for_memory (DBusConnection *connection)
437 while (dbus_connection_get_dispatch_status (connection) ==
438 DBUS_DISPATCH_NEED_MEMORY)
439 _dbus_wait_for_memory ();
441 return dbus_connection_borrow_message (connection);
445 warn_unexpected_real (DBusConnection *connection,
446 DBusMessage *message,
447 const char *expected,
448 const char *function,
452 _dbus_warn ("%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s\n",
454 dbus_message_get_interface (message) ?
455 dbus_message_get_interface (message) : "(unset)",
456 dbus_message_get_member (message) ?
457 dbus_message_get_member (message) : "(unset)",
458 dbus_message_get_error_name (message) ?
459 dbus_message_get_error_name (message) : "(unset)",
463 _dbus_warn ("%s:%d received no message on %p, expecting %s\n",
464 function, line, connection, expected);
467 #define warn_unexpected(connection, message, expected) \
468 warn_unexpected_real (connection, message, expected, _DBUS_FUNCTION_NAME, __LINE__)
471 verbose_message_received (DBusConnection *connection,
472 DBusMessage *message)
474 _dbus_verbose ("Received message interface \"%s\" member \"%s\" error name \"%s\" on %p\n",
475 dbus_message_get_interface (message) ?
476 dbus_message_get_interface (message) : "(unset)",
477 dbus_message_get_member (message) ?
478 dbus_message_get_member (message) : "(unset)",
479 dbus_message_get_error_name (message) ?
480 dbus_message_get_error_name (message) : "(unset)",
493 ServiceInfoKind expected_kind;
494 const char *expected_service_name;
496 DBusConnection *skip_connection;
497 } CheckServiceOwnerChangedData;
500 check_service_owner_changed_foreach (DBusConnection *connection,
503 CheckServiceOwnerChangedData *d = data;
504 DBusMessage *message;
506 char *service_name, *old_owner, *new_owner;
508 if (d->expected_kind == SERVICE_CREATED
509 && connection == d->skip_connection)
512 dbus_error_init (&error);
515 message = pop_message_waiting_for_memory (connection);
518 _dbus_warn ("Did not receive a message on %p, expecting %s\n",
519 connection, "ServiceOwnerChanged");
522 else if (!dbus_message_is_signal (message,
523 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
524 "ServiceOwnerChanged"))
526 warn_unexpected (connection, message, "ServiceOwnerChanged");
532 reget_service_info_data:
537 dbus_message_get_args (message, &error,
538 DBUS_TYPE_STRING, &service_name,
539 DBUS_TYPE_STRING, &old_owner,
540 DBUS_TYPE_STRING, &new_owner,
543 if (dbus_error_is_set (&error))
545 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
547 dbus_free (service_name);
548 dbus_free (old_owner);
549 dbus_free (new_owner);
550 dbus_error_free (&error);
551 _dbus_wait_for_memory ();
552 goto reget_service_info_data;
556 _dbus_warn ("Did not get the expected arguments\n");
561 if ((d->expected_kind == SERVICE_CREATED && ( old_owner[0] || !new_owner[0]))
562 || (d->expected_kind == OWNER_CHANGED && (!old_owner[0] || !new_owner[0]))
563 || (d->expected_kind == SERVICE_DELETED && (!old_owner[0] || new_owner[0])))
565 _dbus_warn ("inconsistent ServiceOwnerChanged arguments");
569 if (strcmp (service_name, d->expected_service_name) != 0)
571 _dbus_warn ("expected info on service %s, got info on %s\n",
572 d->expected_service_name,
577 if (*service_name == ':' && new_owner[0]
578 && strcmp (service_name, new_owner) != 0)
580 _dbus_warn ("inconsistent ServiceOwnedChanged message (\"%s\" [ %s -> %s ])\n",
581 service_name, old_owner, new_owner);
589 dbus_free (service_name);
590 dbus_free (old_owner);
591 dbus_free (new_owner);
592 dbus_error_free (&error);
595 dbus_message_unref (message);
602 kill_client_connection (BusContext *context,
603 DBusConnection *connection)
607 CheckServiceOwnerChangedData socd;
609 _dbus_verbose ("killing connection %p\n", connection);
611 s = dbus_bus_get_base_service (connection);
612 _dbus_assert (s != NULL);
614 while ((base_service = _dbus_strdup (s)) == NULL)
615 _dbus_wait_for_memory ();
617 dbus_connection_ref (connection);
619 /* kick in the disconnect handler that unrefs the connection */
620 dbus_connection_disconnect (connection);
622 bus_test_run_everything (context);
624 _dbus_assert (bus_test_client_listed (connection));
626 /* Run disconnect handler in test.c */
627 if (bus_connection_dispatch_one_message (connection))
628 _dbus_assert_not_reached ("something received on connection being killed other than the disconnect");
630 _dbus_assert (!dbus_connection_get_is_connected (connection));
631 dbus_connection_unref (connection);
633 _dbus_assert (!bus_test_client_listed (connection));
635 socd.expected_kind = SERVICE_DELETED;
636 socd.expected_service_name = base_service;
638 socd.skip_connection = NULL;
640 bus_test_clients_foreach (check_service_owner_changed_foreach,
643 dbus_free (base_service);
646 _dbus_assert_not_reached ("didn't get the expected ServiceOwnerChanged (deletion) messages");
648 if (!check_no_leftovers (context))
649 _dbus_assert_not_reached ("stuff left in message queues after disconnecting a client");
653 kill_client_connection_unchecked (DBusConnection *connection)
655 /* This kills the connection without expecting it to affect
656 * the rest of the bus.
658 _dbus_verbose ("Unchecked kill of connection %p\n", connection);
660 dbus_connection_ref (connection);
661 dbus_connection_disconnect (connection);
662 /* dispatching disconnect handler will unref once */
663 if (bus_connection_dispatch_one_message (connection))
664 _dbus_assert_not_reached ("message other than disconnect dispatched after failure to register");
666 _dbus_assert (!bus_test_client_listed (connection));
667 dbus_connection_unref (connection);
673 } CheckNoMessagesData;
676 check_no_messages_foreach (DBusConnection *connection,
679 CheckNoMessagesData *d = data;
680 DBusMessage *message;
682 message = pop_message_waiting_for_memory (connection);
685 warn_unexpected (connection, message, "no messages");
691 dbus_message_unref (message);
696 check_no_leftovers (BusContext *context)
698 CheckNoMessagesData nmd;
701 bus_test_clients_foreach (check_no_messages_foreach,
710 /* returns TRUE if the correct thing happens,
711 * but the correct thing may include OOM errors.
714 check_hello_message (BusContext *context,
715 DBusConnection *connection)
717 DBusMessage *message;
718 dbus_uint32_t serial;
725 dbus_error_init (&error);
730 _dbus_verbose ("check_hello_message for %p\n", connection);
732 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
733 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
734 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
740 if (!dbus_connection_send (connection, message, &serial))
742 dbus_message_unref (message);
746 dbus_message_unref (message);
749 /* send our message */
750 bus_test_run_clients_loop (TRUE);
752 dbus_connection_ref (connection); /* because we may get disconnected */
753 block_connection_until_message_from_bus (context, connection);
755 if (!dbus_connection_get_is_connected (connection))
757 _dbus_verbose ("connection was disconnected\n");
759 dbus_connection_unref (connection);
764 dbus_connection_unref (connection);
766 message = pop_message_waiting_for_memory (connection);
769 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
770 "Hello", serial, connection);
774 verbose_message_received (connection, message);
776 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
778 _dbus_warn ("Message has wrong sender %s\n",
779 dbus_message_get_sender (message) ?
780 dbus_message_get_sender (message) : "(none)");
784 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
786 if (dbus_message_is_error (message,
787 DBUS_ERROR_NO_MEMORY))
789 ; /* good, this is a valid response */
793 warn_unexpected (connection, message, "not this error");
800 CheckServiceOwnerChangedData socd;
802 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
804 ; /* good, expected */
808 warn_unexpected (connection, message, "method return for Hello");
813 retry_get_hello_name:
814 if (!dbus_message_get_args (message, &error,
815 DBUS_TYPE_STRING, &name,
818 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
820 _dbus_verbose ("no memory to get service name arg from hello\n");
821 dbus_error_free (&error);
822 _dbus_wait_for_memory ();
823 goto retry_get_hello_name;
827 _dbus_assert (dbus_error_is_set (&error));
828 _dbus_warn ("Did not get the expected single string argument to hello\n");
833 _dbus_verbose ("Got hello name: %s\n", name);
835 while (!dbus_bus_set_base_service (connection, name))
836 _dbus_wait_for_memory ();
838 socd.expected_kind = SERVICE_CREATED;
839 socd.expected_service_name = name;
841 socd.skip_connection = connection; /* we haven't done AddMatch so won't get it ourselves */
842 bus_test_clients_foreach (check_service_owner_changed_foreach,
848 /* Client should also have gotten ServiceAcquired */
849 dbus_message_unref (message);
850 message = pop_message_waiting_for_memory (connection);
853 _dbus_warn ("Expecting %s, got nothing\n",
857 if (! dbus_message_is_signal (message, DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
860 _dbus_warn ("Expecting %s, got smthg else\n",
865 retry_get_acquired_name:
866 if (!dbus_message_get_args (message, &error,
867 DBUS_TYPE_STRING, &acquired,
870 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
872 _dbus_verbose ("no memory to get service name arg from acquired\n");
873 dbus_error_free (&error);
874 _dbus_wait_for_memory ();
875 goto retry_get_acquired_name;
879 _dbus_assert (dbus_error_is_set (&error));
880 _dbus_warn ("Did not get the expected single string argument to ServiceAcquired\n");
885 _dbus_verbose ("Got acquired name: %s\n", acquired);
887 if (strcmp (acquired, name) != 0)
889 _dbus_warn ("Acquired name is %s but expected %s\n",
895 if (!check_no_leftovers (context))
901 dbus_error_free (&error);
904 dbus_free (acquired);
907 dbus_message_unref (message);
912 /* returns TRUE if the correct thing happens,
913 * but the correct thing may include OOM errors.
916 check_double_hello_message (BusContext *context,
917 DBusConnection *connection)
919 DBusMessage *message;
920 dbus_uint32_t serial;
925 dbus_error_init (&error);
928 _dbus_verbose ("check_double_hello_message for %p\n", connection);
930 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
931 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
932 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
938 if (!dbus_connection_send (connection, message, &serial))
940 dbus_message_unref (message);
944 dbus_message_unref (message);
947 /* send our message */
948 bus_test_run_clients_loop (TRUE);
950 dbus_connection_ref (connection); /* because we may get disconnected */
951 block_connection_until_message_from_bus (context, connection);
953 if (!dbus_connection_get_is_connected (connection))
955 _dbus_verbose ("connection was disconnected\n");
957 dbus_connection_unref (connection);
962 dbus_connection_unref (connection);
964 message = pop_message_waiting_for_memory (connection);
967 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
968 "Hello", serial, connection);
972 verbose_message_received (connection, message);
974 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
976 _dbus_warn ("Message has wrong sender %s\n",
977 dbus_message_get_sender (message) ?
978 dbus_message_get_sender (message) : "(none)");
982 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
984 warn_unexpected (connection, message, "method return for Hello");
988 if (!check_no_leftovers (context))
994 dbus_error_free (&error);
997 dbus_message_unref (message);
1002 /* returns TRUE if the correct thing happens,
1003 * but the correct thing may include OOM errors.
1006 check_get_connection_unix_user (BusContext *context,
1007 DBusConnection *connection)
1009 DBusMessage *message;
1010 dbus_uint32_t serial;
1013 const char *base_service_name;
1017 dbus_error_init (&error);
1020 _dbus_verbose ("check_get_connection_unix_user for %p\n", connection);
1022 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1023 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1024 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1025 "GetConnectionUnixUser");
1027 if (message == NULL)
1030 base_service_name = dbus_bus_get_base_service (connection);
1032 if (!dbus_message_append_args (message,
1033 DBUS_TYPE_STRING, base_service_name,
1036 dbus_message_unref (message);
1040 if (!dbus_connection_send (connection, message, &serial))
1042 dbus_message_unref (message);
1046 /* send our message */
1047 bus_test_run_clients_loop (TRUE);
1049 dbus_message_unref (message);
1052 dbus_connection_ref (connection); /* because we may get disconnected */
1053 block_connection_until_message_from_bus (context, connection);
1055 if (!dbus_connection_get_is_connected (connection))
1057 _dbus_verbose ("connection was disconnected\n");
1059 dbus_connection_unref (connection);
1064 dbus_connection_unref (connection);
1066 message = pop_message_waiting_for_memory (connection);
1067 if (message == NULL)
1069 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1070 "GetConnectionUnixUser", serial, connection);
1074 verbose_message_received (connection, message);
1076 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1078 if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
1080 ; /* good, this is a valid response */
1084 warn_unexpected (connection, message, "not this error");
1091 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1093 ; /* good, expected */
1097 warn_unexpected (connection, message,
1098 "method_return for GetConnectionUnixUser");
1105 if (!dbus_message_get_args (message, &error,
1106 DBUS_TYPE_UINT32, &uid,
1109 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1111 _dbus_verbose ("no memory to get uid by GetConnectionUnixUser\n");
1112 dbus_error_free (&error);
1113 _dbus_wait_for_memory ();
1114 goto retry_get_property;
1118 _dbus_assert (dbus_error_is_set (&error));
1119 _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixUser\n");
1125 if (!check_no_leftovers (context))
1131 dbus_error_free (&error);
1134 dbus_message_unref (message);
1139 /* returns TRUE if the correct thing happens,
1140 * but the correct thing may include OOM errors.
1143 check_get_connection_unix_process_id (BusContext *context,
1144 DBusConnection *connection)
1146 DBusMessage *message;
1147 dbus_uint32_t serial;
1150 const char *base_service_name;
1154 dbus_error_init (&error);
1157 _dbus_verbose ("check_get_connection_unix_process_id for %p\n", connection);
1159 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1160 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1161 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1162 "GetConnectionUnixProcessID");
1164 if (message == NULL)
1167 base_service_name = dbus_bus_get_base_service (connection);
1169 if (!dbus_message_append_args (message,
1170 DBUS_TYPE_STRING, base_service_name,
1173 dbus_message_unref (message);
1177 if (!dbus_connection_send (connection, message, &serial))
1179 dbus_message_unref (message);
1183 /* send our message */
1184 bus_test_run_clients_loop (TRUE);
1186 dbus_message_unref (message);
1189 dbus_connection_ref (connection); /* because we may get disconnected */
1190 block_connection_until_message_from_bus (context, connection);
1192 if (!dbus_connection_get_is_connected (connection))
1194 _dbus_verbose ("connection was disconnected\n");
1196 dbus_connection_unref (connection);
1201 dbus_connection_unref (connection);
1203 message = pop_message_waiting_for_memory (connection);
1204 if (message == NULL)
1206 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1207 "GetConnectionUnixProcessID", serial, connection);
1211 verbose_message_received (connection, message);
1213 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1215 if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
1217 ; /* good, this is a valid response */
1221 warn_unexpected (connection, message, "not this error");
1228 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1230 ; /* good, expected */
1234 warn_unexpected (connection, message,
1235 "method_return for GetConnectionUnixProcessID");
1242 if (!dbus_message_get_args (message, &error,
1243 DBUS_TYPE_UINT32, &pid,
1246 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1248 _dbus_verbose ("no memory to get pid by GetConnectionUnixProcessID\n");
1249 dbus_error_free (&error);
1250 _dbus_wait_for_memory ();
1251 goto retry_get_property;
1255 _dbus_assert (dbus_error_is_set (&error));
1256 _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixProcessID\n");
1261 /* test if returned pid is the same as our own pid
1263 * @todo It would probably be good to restructure the tests
1264 * in a way so our parent is the bus that we're testing
1265 * cause then we can test that the pid returned matches
1268 if (pid != (dbus_uint32_t) _dbus_getpid ())
1270 _dbus_assert (dbus_error_is_set (&error));
1271 _dbus_warn ("Result from GetConnectionUnixProcessID is not our own pid\n");
1277 if (!check_no_leftovers (context))
1283 dbus_error_free (&error);
1286 dbus_message_unref (message);
1291 /* returns TRUE if the correct thing happens,
1292 * but the correct thing may include OOM errors.
1295 check_add_match_all (BusContext *context,
1296 DBusConnection *connection)
1298 DBusMessage *message;
1300 dbus_uint32_t serial;
1304 dbus_error_init (&error);
1307 _dbus_verbose ("check_add_match_all for %p\n", connection);
1309 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1310 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1311 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1314 if (message == NULL)
1317 /* empty string match rule matches everything */
1318 if (!dbus_message_append_args (message, DBUS_TYPE_STRING, "",
1321 dbus_message_unref (message);
1325 if (!dbus_connection_send (connection, message, &serial))
1327 dbus_message_unref (message);
1331 dbus_message_unref (message);
1334 /* send our message */
1335 bus_test_run_clients_loop (TRUE);
1337 dbus_connection_ref (connection); /* because we may get disconnected */
1338 block_connection_until_message_from_bus (context, connection);
1340 if (!dbus_connection_get_is_connected (connection))
1342 _dbus_verbose ("connection was disconnected\n");
1344 dbus_connection_unref (connection);
1349 dbus_connection_unref (connection);
1351 message = pop_message_waiting_for_memory (connection);
1352 if (message == NULL)
1354 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1355 "AddMatch", serial, connection);
1359 verbose_message_received (connection, message);
1361 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1363 _dbus_warn ("Message has wrong sender %s\n",
1364 dbus_message_get_sender (message) ?
1365 dbus_message_get_sender (message) : "(none)");
1369 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1371 if (dbus_message_is_error (message,
1372 DBUS_ERROR_NO_MEMORY))
1374 ; /* good, this is a valid response */
1378 warn_unexpected (connection, message, "not this error");
1385 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1387 ; /* good, expected */
1388 _dbus_assert (dbus_message_get_reply_serial (message) == serial);
1392 warn_unexpected (connection, message, "method return for AddMatch");
1398 if (!check_no_leftovers (context))
1404 dbus_error_free (&error);
1407 dbus_message_unref (message);
1412 /* returns TRUE if the correct thing happens,
1413 * but the correct thing may include OOM errors.
1416 check_hello_connection (BusContext *context)
1418 DBusConnection *connection;
1421 dbus_error_init (&error);
1423 connection = dbus_connection_open ("debug-pipe:name=test-server", &error);
1424 if (connection == NULL)
1426 _DBUS_ASSERT_ERROR_IS_SET (&error);
1427 dbus_error_free (&error);
1431 if (!bus_setup_debug_client (connection))
1433 dbus_connection_disconnect (connection);
1434 dbus_connection_unref (connection);
1438 if (!check_hello_message (context, connection))
1441 if (dbus_bus_get_base_service (connection) == NULL)
1443 /* We didn't successfully register, so we can't
1444 * do the usual kill_client_connection() checks
1446 kill_client_connection_unchecked (connection);
1450 if (!check_add_match_all (context, connection))
1453 kill_client_connection (context, connection);
1459 #define NONEXISTENT_SERVICE_NAME "test.this.service.does.not.exist.ewuoiurjdfxcvn"
1461 /* returns TRUE if the correct thing happens,
1462 * but the correct thing may include OOM errors.
1465 check_nonexistent_service_activation (BusContext *context,
1466 DBusConnection *connection)
1468 DBusMessage *message;
1469 dbus_uint32_t serial;
1472 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
1473 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
1474 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1477 if (message == NULL)
1480 if (!dbus_message_append_args (message,
1481 DBUS_TYPE_STRING, NONEXISTENT_SERVICE_NAME,
1482 DBUS_TYPE_UINT32, 0,
1485 dbus_message_unref (message);
1489 if (!dbus_connection_send (connection, message, &serial))
1491 dbus_message_unref (message);
1495 dbus_message_unref (message);
1498 bus_test_run_everything (context);
1499 block_connection_until_message_from_bus (context, connection);
1500 bus_test_run_everything (context);
1502 if (!dbus_connection_get_is_connected (connection))
1504 _dbus_verbose ("connection was disconnected\n");
1510 message = pop_message_waiting_for_memory (connection);
1511 if (message == NULL)
1513 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1514 "ActivateService", serial, connection);
1518 verbose_message_received (connection, message);
1520 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1522 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1524 _dbus_warn ("Message has wrong sender %s\n",
1525 dbus_message_get_sender (message) ?
1526 dbus_message_get_sender (message) : "(none)");
1530 if (dbus_message_is_error (message,
1531 DBUS_ERROR_NO_MEMORY))
1533 ; /* good, this is a valid response */
1535 else if (dbus_message_is_error (message,
1536 DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND))
1538 ; /* good, this is expected also */
1542 warn_unexpected (connection, message, "not this error");
1548 _dbus_warn ("Did not expect to successfully activate %s\n",
1549 NONEXISTENT_SERVICE_NAME);
1557 dbus_message_unref (message);
1562 /* returns TRUE if the correct thing happens,
1563 * but the correct thing may include OOM errors.
1566 check_nonexistent_service_auto_activation (BusContext *context,
1567 DBusConnection *connection)
1569 DBusMessage *message;
1570 dbus_uint32_t serial;
1573 message = dbus_message_new_method_call (NONEXISTENT_SERVICE_NAME,
1574 "/org/freedesktop/TestSuite",
1575 "org.freedesktop.TestSuite",
1578 if (message == NULL)
1581 dbus_message_set_auto_activation (message, TRUE);
1583 if (!dbus_connection_send (connection, message, &serial))
1585 dbus_message_unref (message);
1589 dbus_message_unref (message);
1592 bus_test_run_everything (context);
1593 block_connection_until_message_from_bus (context, connection);
1594 bus_test_run_everything (context);
1596 if (!dbus_connection_get_is_connected (connection))
1598 _dbus_verbose ("connection was disconnected\n");
1604 message = pop_message_waiting_for_memory (connection);
1606 if (message == NULL)
1608 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1609 "Echo message (auto activation)", serial, connection);
1613 verbose_message_received (connection, message);
1615 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1617 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
1619 _dbus_warn ("Message has wrong sender %s\n",
1620 dbus_message_get_sender (message) ?
1621 dbus_message_get_sender (message) : "(none)");
1625 if (dbus_message_is_error (message,
1626 DBUS_ERROR_NO_MEMORY))
1628 ; /* good, this is a valid response */
1630 else if (dbus_message_is_error (message,
1631 DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND))
1633 ; /* good, this is expected also */
1637 warn_unexpected (connection, message, "not this error");
1643 _dbus_warn ("Did not expect to successfully activate %s\n",
1644 NONEXISTENT_SERVICE_NAME);
1652 dbus_message_unref (message);
1658 check_base_service_activated (BusContext *context,
1659 DBusConnection *connection,
1660 DBusMessage *initial_message,
1661 char **base_service_p)
1663 DBusMessage *message;
1666 char *base_service, *base_service_from_bus, *old_owner;
1670 dbus_error_init (&error);
1671 base_service = NULL;
1673 base_service_from_bus = NULL;
1675 message = initial_message;
1676 dbus_message_ref (message);
1678 if (dbus_message_is_signal (message,
1679 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1680 "ServiceOwnerChanged"))
1682 CheckServiceOwnerChangedData socd;
1684 reget_service_name_arg:
1685 base_service = NULL;
1687 base_service_from_bus = NULL;
1689 if (!dbus_message_get_args (message, &error,
1690 DBUS_TYPE_STRING, &base_service,
1691 DBUS_TYPE_STRING, &old_owner,
1692 DBUS_TYPE_STRING, &base_service_from_bus,
1695 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1697 dbus_error_free (&error);
1698 dbus_free (base_service);
1699 dbus_free (old_owner);
1700 dbus_free (base_service_from_bus);
1701 _dbus_wait_for_memory ();
1702 goto reget_service_name_arg;
1706 _dbus_warn ("Message %s doesn't have a service name: %s\n",
1707 "ServiceOwnerChanged (creation)",
1713 if (*base_service != ':')
1715 _dbus_warn ("Expected base service activation, got \"%s\" instead\n",
1720 if (strcmp (base_service, base_service_from_bus) != 0)
1722 _dbus_warn ("Expected base service activation, got \"%s\" instead with owner \"%s\"\n",
1723 base_service, base_service_from_bus);
1729 _dbus_warn ("Received an old_owner argument during base service activation, \"%s\"\n",
1734 socd.expected_kind = SERVICE_CREATED;
1735 socd.expected_service_name = base_service;
1736 socd.failed = FALSE;
1737 socd.skip_connection = connection;
1738 bus_test_clients_foreach (check_service_owner_changed_foreach,
1746 warn_unexpected (connection, message, "ServiceOwnerChanged (creation) for base service");
1755 *base_service_p = base_service;
1756 base_service = NULL;
1761 dbus_message_unref (message);
1762 dbus_free (base_service);
1763 dbus_free (base_service_from_bus);
1764 dbus_free (old_owner);
1765 dbus_error_free (&error);
1771 check_service_activated (BusContext *context,
1772 DBusConnection *connection,
1773 const char *activated_name,
1774 const char *base_service_name,
1775 DBusMessage *initial_message)
1777 DBusMessage *message;
1780 dbus_uint32_t activation_result;
1784 dbus_error_init (&error);
1786 message = initial_message;
1787 dbus_message_ref (message);
1789 if (dbus_message_is_signal (message,
1790 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1791 "ServiceOwnerChanged"))
1793 CheckServiceOwnerChangedData socd;
1794 char *service_name, *base_service_from_bus, *old_owner;
1796 reget_service_name_arg:
1797 service_name = NULL;
1799 base_service_from_bus = NULL;
1801 if (!dbus_message_get_args (message, &error,
1802 DBUS_TYPE_STRING, &service_name,
1803 DBUS_TYPE_STRING, &old_owner,
1804 DBUS_TYPE_STRING, &base_service_from_bus,
1807 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1809 dbus_error_free (&error);
1810 dbus_free (service_name);
1811 dbus_free (old_owner);
1812 dbus_free (base_service_from_bus);
1813 _dbus_wait_for_memory ();
1814 goto reget_service_name_arg;
1818 _dbus_warn ("Message %s doesn't have a service name: %s\n",
1819 "ServiceOwnerChanged (creation)",
1821 dbus_free (service_name);
1822 dbus_free (old_owner);
1823 dbus_free (base_service_from_bus);
1828 if (strcmp (service_name, activated_name) != 0)
1830 _dbus_warn ("Expected to see service %s created, saw %s instead\n",
1831 activated_name, service_name);
1832 dbus_free (service_name);
1833 dbus_free (old_owner);
1834 dbus_free (base_service_from_bus);
1838 if (strcmp (base_service_name, base_service_from_bus) != 0)
1840 _dbus_warn ("ServiceOwnerChanged reports wrong base service: %s owner, expected %s instead\n",
1841 base_service_from_bus, base_service_name);
1842 dbus_free (service_name);
1843 dbus_free (old_owner);
1844 dbus_free (base_service_from_bus);
1847 dbus_free (base_service_from_bus);
1851 _dbus_warn ("expected a %s, got a %s\n",
1852 "ServiceOwnerChanged (creation)",
1853 "ServiceOwnerChanged (change)");
1854 dbus_free (service_name);
1855 dbus_free (old_owner);
1858 dbus_free (old_owner);
1860 socd.expected_kind = SERVICE_CREATED;
1861 socd.skip_connection = connection;
1862 socd.failed = FALSE;
1863 socd.expected_service_name = service_name;
1864 bus_test_clients_foreach (check_service_owner_changed_foreach,
1867 dbus_free (service_name);
1872 dbus_message_unref (message);
1873 message = pop_message_waiting_for_memory (connection);
1874 if (message == NULL)
1876 _dbus_warn ("Expected a reply to %s, got nothing\n",
1883 warn_unexpected (connection, message, "ServiceOwnerChanged for the activated name");
1888 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
1890 warn_unexpected (connection, message, "reply to ActivateService");
1895 activation_result = 0;
1896 if (!dbus_message_get_args (message, &error,
1897 DBUS_TYPE_UINT32, &activation_result,
1900 if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1902 _dbus_warn ("Did not have activation result first argument to %s: %s\n",
1903 "ActivateService", error.message);
1907 dbus_error_free (&error);
1911 if (activation_result == DBUS_ACTIVATION_REPLY_ACTIVATED)
1913 else if (activation_result == DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE)
1917 _dbus_warn ("Activation result was 0x%x, no good.\n",
1923 dbus_message_unref (message);
1926 if (!check_no_leftovers (context))
1928 _dbus_warn ("Messages were left over after verifying existent activation results\n");
1936 dbus_message_unref (message);
1937 dbus_error_free (&error);
1943 check_service_auto_activated (BusContext *context,
1944 DBusConnection *connection,
1945 const char *activated_name,
1946 const char *base_service_name,
1947 DBusMessage *initial_message)
1949 DBusMessage *message;
1955 dbus_error_init (&error);
1957 message = initial_message;
1958 dbus_message_ref (message);
1960 if (dbus_message_is_signal (message,
1961 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
1962 "ServiceOwnerChanged"))
1965 CheckServiceOwnerChangedData socd;
1967 reget_service_name_arg:
1968 if (!dbus_message_get_args (message, &error,
1969 DBUS_TYPE_STRING, &service_name,
1972 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1974 dbus_error_free (&error);
1975 _dbus_wait_for_memory ();
1976 goto reget_service_name_arg;
1980 _dbus_warn ("Message %s doesn't have a service name: %s\n",
1981 "ServiceOwnerChanged",
1983 dbus_error_free (&error);
1988 if (strcmp (service_name, activated_name) != 0)
1990 _dbus_warn ("Expected to see service %s created, saw %s instead\n",
1991 activated_name, service_name);
1992 dbus_free (service_name);
1996 socd.expected_kind = SERVICE_CREATED;
1997 socd.expected_service_name = service_name;
1998 socd.failed = FALSE;
1999 socd.skip_connection = connection;
2000 bus_test_clients_foreach (check_service_owner_changed_foreach,
2003 dbus_free (service_name);
2008 /* Note that this differs from regular activation in that we don't get a
2009 * reply to ActivateService here.
2012 dbus_message_unref (message);
2017 warn_unexpected (connection, message, "ServiceOwnerChanged for the activated name");
2026 dbus_message_unref (message);
2032 check_service_deactivated (BusContext *context,
2033 DBusConnection *connection,
2034 const char *activated_name,
2035 const char *base_service)
2038 CheckServiceOwnerChangedData socd;
2042 /* Now we are expecting ServiceOwnerChanged (deletion) messages for the base
2043 * service and the activated_name. The base service
2044 * notification is required to come last.
2046 socd.expected_kind = SERVICE_DELETED;
2047 socd.expected_service_name = activated_name;
2048 socd.failed = FALSE;
2049 socd.skip_connection = NULL;
2050 bus_test_clients_foreach (check_service_owner_changed_foreach,
2056 socd.expected_kind = SERVICE_DELETED;
2057 socd.expected_service_name = base_service;
2058 socd.failed = FALSE;
2059 socd.skip_connection = NULL;
2060 bus_test_clients_foreach (check_service_owner_changed_foreach,
2073 check_send_exit_to_service (BusContext *context,
2074 DBusConnection *connection,
2075 const char *service_name,
2076 const char *base_service)
2078 dbus_bool_t got_error;
2079 DBusMessage *message;
2080 dbus_uint32_t serial;
2083 _dbus_verbose ("Sending exit message to the test service\n");
2087 /* Kill off the test service by sending it a quit message */
2088 message = dbus_message_new_method_call (service_name,
2089 "/org/freedesktop/TestSuite",
2090 "org.freedesktop.TestSuite",
2093 if (message == NULL)
2095 /* Do this again; we still need the service to exit... */
2096 if (!check_send_exit_to_service (context, connection,
2097 service_name, base_service))
2103 if (!dbus_connection_send (connection, message, &serial))
2105 dbus_message_unref (message);
2107 /* Do this again; we still need the service to exit... */
2108 if (!check_send_exit_to_service (context, connection,
2109 service_name, base_service))
2115 dbus_message_unref (message);
2119 bus_test_run_clients_loop (TRUE);
2121 /* read it in and write it out to test service */
2122 bus_test_run_bus_loop (context, FALSE);
2124 /* see if we got an error during message bus dispatching */
2125 bus_test_run_clients_loop (FALSE);
2126 message = borrow_message_waiting_for_memory (connection);
2127 got_error = message != NULL && dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
2130 dbus_connection_return_message (connection, message);
2136 /* If no error, wait for the test service to exit */
2137 block_connection_until_message_from_bus (context, connection);
2139 bus_test_run_everything (context);
2144 message = pop_message_waiting_for_memory (connection);
2145 _dbus_assert (message != NULL);
2147 if (dbus_message_get_reply_serial (message) != serial)
2149 warn_unexpected (connection, message,
2150 "error with the correct reply serial");
2154 if (!dbus_message_is_error (message,
2155 DBUS_ERROR_NO_MEMORY))
2157 warn_unexpected (connection, message,
2158 "a no memory error from asking test service to exit");
2162 _dbus_verbose ("Got error %s when asking test service to exit\n",
2163 dbus_message_get_error_name (message));
2165 /* Do this again; we still need the service to exit... */
2166 if (!check_send_exit_to_service (context, connection,
2167 service_name, base_service))
2172 if (!check_service_deactivated (context, connection,
2173 service_name, base_service))
2176 /* Should now have a NoReply error from the Exit() method
2177 * call; it should have come after all the deactivation
2180 message = pop_message_waiting_for_memory (connection);
2182 if (message == NULL)
2184 warn_unexpected (connection, NULL,
2185 "reply to Exit() method call");
2188 if (!dbus_message_is_error (message,
2189 DBUS_ERROR_NO_REPLY))
2191 warn_unexpected (connection, NULL,
2192 "NoReply error from Exit() method call");
2196 if (dbus_message_get_reply_serial (message) != serial)
2198 warn_unexpected (connection, message,
2199 "error with the correct reply serial");
2203 _dbus_verbose ("Got error %s after test service exited\n",
2204 dbus_message_get_error_name (message));
2206 if (!check_no_leftovers (context))
2208 _dbus_warn ("Messages were left over after %s\n",
2209 _DBUS_FUNCTION_NAME);
2218 dbus_message_unref (message);
2224 check_got_error (BusContext *context,
2225 DBusConnection *connection,
2226 const char *first_error_name,
2229 DBusMessage *message;
2232 dbus_bool_t error_found;
2233 const char *error_name;
2237 message = pop_message_waiting_for_memory (connection);
2238 if (message == NULL)
2240 _dbus_warn ("Did not get an expected error\n");
2244 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
2246 warn_unexpected (connection, message, "an error");
2251 error_found = FALSE;
2253 va_start (ap, first_error_name);
2254 error_name = first_error_name;
2255 while (error_name != NULL)
2257 if (dbus_message_is_error (message, error_name))
2262 error_name = va_arg (ap, char*);
2268 _dbus_warn ("Expected error %s or other, got %s instead\n",
2270 dbus_message_get_error_name (message));
2278 dbus_message_unref (message);
2285 GOT_SERVICE_CREATED,
2286 GOT_SERVICE_DELETED,
2291 static GotServiceInfo
2292 check_got_service_info (DBusMessage *message)
2294 GotServiceInfo message_kind;
2296 if (dbus_message_is_signal (message,
2297 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
2298 "ServiceOwnerChanged"))
2301 char *service_name, *old_owner, *new_owner;
2302 dbus_error_init (&error);
2304 reget_service_info_data:
2305 service_name = NULL;
2309 dbus_message_get_args (message, &error,
2310 DBUS_TYPE_STRING, &service_name,
2311 DBUS_TYPE_STRING, &old_owner,
2312 DBUS_TYPE_STRING, &new_owner,
2314 if (dbus_error_is_set (&error))
2316 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
2318 dbus_error_free (&error);
2319 dbus_free (service_name);
2320 dbus_free (old_owner);
2321 dbus_free (new_owner);
2322 goto reget_service_info_data;
2326 _dbus_warn ("unexpected arguments for ServiceOwnerChanged message");
2327 message_kind = GOT_SOMETHING_ELSE;
2330 else if (!old_owner[0])
2331 message_kind = GOT_SERVICE_CREATED;
2332 else if (!new_owner[0])
2333 message_kind = GOT_SERVICE_DELETED;
2335 message_kind = GOT_SOMETHING_ELSE;
2337 dbus_free (service_name);
2338 dbus_free (old_owner);
2339 dbus_free (new_owner);
2340 dbus_error_free (&error);
2342 else if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2343 message_kind = GOT_ERROR;
2345 message_kind = GOT_SOMETHING_ELSE;
2347 return message_kind;
2350 #define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"
2352 /* returns TRUE if the correct thing happens,
2353 * but the correct thing may include OOM errors.
2356 check_existent_service_activation (BusContext *context,
2357 DBusConnection *connection)
2359 DBusMessage *message;
2360 dbus_uint32_t serial;
2364 base_service = NULL;
2366 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
2367 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
2368 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
2371 if (message == NULL)
2374 if (!dbus_message_append_args (message,
2375 DBUS_TYPE_STRING, EXISTENT_SERVICE_NAME,
2376 DBUS_TYPE_UINT32, 0,
2379 dbus_message_unref (message);
2383 if (!dbus_connection_send (connection, message, &serial))
2385 dbus_message_unref (message);
2389 dbus_message_unref (message);
2392 bus_test_run_everything (context);
2394 /* now wait for the message bus to hear back from the activated
2397 block_connection_until_message_from_bus (context, connection);
2399 bus_test_run_everything (context);
2401 if (!dbus_connection_get_is_connected (connection))
2403 _dbus_verbose ("connection was disconnected\n");
2409 message = pop_message_waiting_for_memory (connection);
2410 if (message == NULL)
2412 _dbus_warn ("Did not receive any messages after %s %d on %p\n",
2413 "ActivateService", serial, connection);
2417 verbose_message_received (connection, message);
2418 _dbus_verbose (" (after sending %s)\n", "ActivateService");
2420 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2422 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
2424 _dbus_warn ("Message has wrong sender %s\n",
2425 dbus_message_get_sender (message) ?
2426 dbus_message_get_sender (message) : "(none)");
2430 if (dbus_message_is_error (message,
2431 DBUS_ERROR_NO_MEMORY))
2433 ; /* good, this is a valid response */
2435 else if (dbus_message_is_error (message,
2436 DBUS_ERROR_SPAWN_CHILD_EXITED) ||
2437 dbus_message_is_error (message,
2438 DBUS_ERROR_SPAWN_EXEC_FAILED))
2440 ; /* good, this is expected also */
2444 _dbus_warn ("Did not expect error %s\n",
2445 dbus_message_get_error_name (message));
2451 GotServiceInfo message_kind;
2453 if (!check_base_service_activated (context, connection,
2454 message, &base_service))
2457 dbus_message_unref (message);
2460 /* We may need to block here for the test service to exit or finish up */
2461 block_connection_until_message_from_bus (context, connection);
2463 message = dbus_connection_borrow_message (connection);
2464 if (message == NULL)
2466 _dbus_warn ("Did not receive any messages after base service creation notification\n");
2470 message_kind = check_got_service_info (message);
2472 dbus_connection_return_message (connection, message);
2475 switch (message_kind)
2477 case GOT_SOMETHING_ELSE:
2478 _dbus_warn ("Unexpected message after ActivateService "
2479 "(should be an error or a service announcement");
2483 if (!check_got_error (context, connection,
2484 DBUS_ERROR_SPAWN_CHILD_EXITED,
2485 DBUS_ERROR_NO_MEMORY,
2488 /* A service deleted should be coming along now after this error.
2489 * We can also get the error *after* the service deleted.
2494 case GOT_SERVICE_DELETED:
2496 /* The service started up and got a base address, but then
2497 * failed to register under EXISTENT_SERVICE_NAME
2499 CheckServiceOwnerChangedData socd;
2501 socd.expected_kind = SERVICE_DELETED;
2502 socd.expected_service_name = base_service;
2503 socd.failed = FALSE;
2504 socd.skip_connection = NULL;
2506 bus_test_clients_foreach (check_service_owner_changed_foreach,
2512 /* Now we should get an error about the service exiting
2513 * if we didn't get it before.
2515 if (message_kind != GOT_ERROR)
2517 block_connection_until_message_from_bus (context, connection);
2519 /* and process everything again */
2520 bus_test_run_everything (context);
2522 if (!check_got_error (context, connection,
2523 DBUS_ERROR_SPAWN_CHILD_EXITED,
2530 case GOT_SERVICE_CREATED:
2531 message = pop_message_waiting_for_memory (connection);
2532 if (message == NULL)
2534 _dbus_warn ("Failed to pop message we just put back! "
2535 "should have been a ServiceOwnerChanged (creation)\n");
2539 if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
2540 base_service, message))
2543 dbus_message_unref (message);
2546 if (!check_no_leftovers (context))
2548 _dbus_warn ("Messages were left over after successful activation\n");
2552 if (!check_send_exit_to_service (context, connection,
2553 EXISTENT_SERVICE_NAME, base_service))
2564 dbus_message_unref (message);
2567 dbus_free (base_service);
2572 /* returns TRUE if the correct thing happens,
2573 * but the correct thing may include OOM errors.
2576 check_segfault_service_activation (BusContext *context,
2577 DBusConnection *connection)
2579 DBusMessage *message;
2580 dbus_uint32_t serial;
2583 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
2584 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
2585 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
2588 if (message == NULL)
2591 if (!dbus_message_append_args (message,
2593 "org.freedesktop.DBus.TestSuiteSegfaultService",
2594 DBUS_TYPE_UINT32, 0,
2597 dbus_message_unref (message);
2601 if (!dbus_connection_send (connection, message, &serial))
2603 dbus_message_unref (message);
2607 dbus_message_unref (message);
2610 bus_test_run_everything (context);
2611 block_connection_until_message_from_bus (context, connection);
2612 bus_test_run_everything (context);
2614 if (!dbus_connection_get_is_connected (connection))
2616 _dbus_verbose ("connection was disconnected\n");
2622 message = pop_message_waiting_for_memory (connection);
2623 if (message == NULL)
2625 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
2626 "ActivateService", serial, connection);
2630 verbose_message_received (connection, message);
2632 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2634 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
2636 _dbus_warn ("Message has wrong sender %s\n",
2637 dbus_message_get_sender (message) ?
2638 dbus_message_get_sender (message) : "(none)");
2642 if (dbus_message_is_error (message,
2643 DBUS_ERROR_NO_MEMORY))
2645 ; /* good, this is a valid response */
2647 else if (dbus_message_is_error (message,
2648 DBUS_ERROR_SPAWN_CHILD_SIGNALED))
2650 ; /* good, this is expected also */
2654 warn_unexpected (connection, message, "not this error");
2661 _dbus_warn ("Did not expect to successfully activate segfault service\n");
2669 dbus_message_unref (message);
2675 /* returns TRUE if the correct thing happens,
2676 * but the correct thing may include OOM errors.
2679 check_segfault_service_auto_activation (BusContext *context,
2680 DBusConnection *connection)
2682 DBusMessage *message;
2683 dbus_uint32_t serial;
2686 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestSuiteSegfaultService",
2687 "/org/freedesktop/TestSuite",
2688 "org.freedesktop.TestSuite",
2691 if (message == NULL)
2694 dbus_message_set_auto_activation (message, TRUE);
2696 if (!dbus_connection_send (connection, message, &serial))
2698 dbus_message_unref (message);
2702 dbus_message_unref (message);
2705 bus_test_run_everything (context);
2706 block_connection_until_message_from_bus (context, connection);
2707 bus_test_run_everything (context);
2709 if (!dbus_connection_get_is_connected (connection))
2711 _dbus_verbose ("connection was disconnected\n");
2717 message = pop_message_waiting_for_memory (connection);
2718 if (message == NULL)
2720 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
2721 "Echo message (auto activation)", serial, connection);
2725 verbose_message_received (connection, message);
2727 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2729 if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
2731 _dbus_warn ("Message has wrong sender %s\n",
2732 dbus_message_get_sender (message) ?
2733 dbus_message_get_sender (message) : "(none)");
2737 if (dbus_message_is_error (message,
2738 DBUS_ERROR_NO_MEMORY))
2740 ; /* good, this is a valid response */
2742 else if (dbus_message_is_error (message,
2743 DBUS_ERROR_SPAWN_CHILD_SIGNALED))
2745 ; /* good, this is expected also */
2749 warn_unexpected (connection, message, "not this error");
2756 _dbus_warn ("Did not expect to successfully activate segfault service\n");
2764 dbus_message_unref (message);
2769 #define TEST_ECHO_MESSAGE "Test echo message"
2771 /* returns TRUE if the correct thing happens,
2772 * but the correct thing may include OOM errors.
2775 check_existent_service_auto_activation (BusContext *context,
2776 DBusConnection *connection)
2778 DBusMessage *message;
2779 dbus_uint32_t serial;
2783 base_service = NULL;
2785 message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
2786 "/org/freedesktop/TestSuite",
2787 "org.freedesktop.TestSuite",
2790 if (message == NULL)
2793 dbus_message_set_auto_activation (message, TRUE);
2795 if (!dbus_message_append_args (message,
2796 DBUS_TYPE_STRING, TEST_ECHO_MESSAGE,
2799 dbus_message_unref (message);
2803 if (!dbus_connection_send (connection, message, &serial))
2805 dbus_message_unref (message);
2809 dbus_message_unref (message);
2812 bus_test_run_everything (context);
2814 /* now wait for the message bus to hear back from the activated
2817 block_connection_until_message_from_bus (context, connection);
2818 bus_test_run_everything (context);
2820 if (!dbus_connection_get_is_connected (connection))
2822 _dbus_verbose ("connection was disconnected\n");
2828 message = pop_message_waiting_for_memory (connection);
2829 if (message == NULL)
2831 _dbus_warn ("Did not receive any messages after auto activation %d on %p\n",
2832 serial, connection);
2836 verbose_message_received (connection, message);
2837 _dbus_verbose (" (after sending %s)\n", "auto activation");
2839 /* we should get zero or two ServiceOwnerChanged signals */
2840 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL)
2842 GotServiceInfo message_kind;
2844 if (!check_base_service_activated (context, connection,
2845 message, &base_service))
2848 dbus_message_unref (message);
2851 /* We may need to block here for the test service to exit or finish up */
2852 block_connection_until_message_from_bus (context, connection);
2854 /* Should get a service creation notification for the activated
2855 * service name, or a service deletion on the base service name
2857 message = dbus_connection_borrow_message (connection);
2858 if (message == NULL)
2860 _dbus_warn ("No message after auto activation "
2861 "(should be a service announcement)");
2862 dbus_connection_return_message (connection, message);
2867 message_kind = check_got_service_info (message);
2869 dbus_connection_return_message (connection, message);
2872 switch (message_kind)
2874 case GOT_SERVICE_CREATED:
2875 message = pop_message_waiting_for_memory (connection);
2876 if (message == NULL)
2878 _dbus_warn ("Failed to pop message we just put back! "
2879 "should have been a ServiceOwnerChanged (creation)\n");
2883 /* Check that ServiceOwnerChanged (creation) was correctly received */
2884 if (!check_service_auto_activated (context, connection, EXISTENT_SERVICE_NAME,
2885 base_service, message))
2888 dbus_message_unref (message);
2893 case GOT_SERVICE_DELETED:
2895 /* The service started up and got a base address, but then
2896 * failed to register under EXISTENT_SERVICE_NAME
2898 CheckServiceOwnerChangedData socd;
2900 socd.expected_kind = SERVICE_DELETED;
2901 socd.expected_service_name = base_service;
2902 socd.failed = FALSE;
2903 socd.skip_connection = NULL;
2904 bus_test_clients_foreach (check_service_owner_changed_foreach,
2914 case GOT_SOMETHING_ELSE:
2915 _dbus_warn ("Unexpected message after auto activation\n");
2920 /* OK, now we've dealt with ServiceOwnerChanged signals, now should
2921 * come the method reply (or error) from the initial method call
2924 /* Note: if this test is run in OOM mode, it will block when the bus
2925 * doesn't send a reply due to OOM.
2927 block_connection_until_message_from_bus (context, connection);
2929 message = pop_message_waiting_for_memory (connection);
2930 if (message == NULL)
2932 _dbus_warn ("Failed to pop message! Should have been reply from echo message\n");
2936 if (dbus_message_get_reply_serial (message) != serial)
2938 _dbus_warn ("Wrong reply serial\n");
2942 dbus_message_unref (message);
2945 if (!check_send_exit_to_service (context, connection,
2946 EXISTENT_SERVICE_NAME,
2954 dbus_message_unref (message);
2957 dbus_free (base_service);
2965 BusContext *context;
2969 check_oom_check1_func (void *data)
2971 Check1Data *d = data;
2973 if (! (* d->func) (d->context))
2976 if (!check_no_leftovers (d->context))
2978 _dbus_warn ("Messages were left over, should be covered by test suite\n");
2986 check1_try_iterations (BusContext *context,
2987 const char *description,
2993 d.context = context;
2995 if (!_dbus_test_oom_handling (description, check_oom_check1_func,
2997 _dbus_assert_not_reached ("test failed");
3003 BusContext *context;
3004 DBusConnection *connection;
3008 check_oom_check2_func (void *data)
3010 Check2Data *d = data;
3012 if (! (* d->func) (d->context, d->connection))
3015 if (!check_no_leftovers (d->context))
3017 _dbus_warn ("Messages were left over, should be covered by test suite");
3025 check2_try_iterations (BusContext *context,
3026 DBusConnection *connection,
3027 const char *description,
3033 d.context = context;
3034 d.connection = connection;
3036 if (!_dbus_test_oom_handling (description, check_oom_check2_func,
3039 _dbus_warn ("%s failed during oom\n", description);
3040 _dbus_assert_not_reached ("test failed");
3045 bus_dispatch_test (const DBusString *test_data_dir)
3047 BusContext *context;
3048 DBusConnection *foo;
3049 DBusConnection *bar;
3050 DBusConnection *baz;
3053 dbus_error_init (&error);
3055 context = bus_context_new_test (test_data_dir,
3056 "valid-config-files/debug-allow-all.conf");
3057 if (context == NULL)
3060 foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
3062 _dbus_assert_not_reached ("could not alloc connection");
3064 if (!bus_setup_debug_client (foo))
3065 _dbus_assert_not_reached ("could not set up connection");
3067 if (!check_hello_message (context, foo))
3068 _dbus_assert_not_reached ("hello message failed");
3070 if (!check_double_hello_message (context, foo))
3071 _dbus_assert_not_reached ("double hello message failed");
3073 if (!check_add_match_all (context, foo))
3074 _dbus_assert_not_reached ("AddMatch message failed");
3076 bar = dbus_connection_open ("debug-pipe:name=test-server", &error);
3078 _dbus_assert_not_reached ("could not alloc connection");
3080 if (!bus_setup_debug_client (bar))
3081 _dbus_assert_not_reached ("could not set up connection");
3083 if (!check_hello_message (context, bar))
3084 _dbus_assert_not_reached ("hello message failed");
3086 if (!check_add_match_all (context, bar))
3087 _dbus_assert_not_reached ("AddMatch message failed");
3089 baz = dbus_connection_open ("debug-pipe:name=test-server", &error);
3091 _dbus_assert_not_reached ("could not alloc connection");
3093 if (!bus_setup_debug_client (baz))
3094 _dbus_assert_not_reached ("could not set up connection");
3096 if (!check_hello_message (context, baz))
3097 _dbus_assert_not_reached ("hello message failed");
3099 if (!check_add_match_all (context, baz))
3100 _dbus_assert_not_reached ("AddMatch message failed");
3102 if (!check_get_connection_unix_user (context, baz))
3103 _dbus_assert_not_reached ("GetConnectionUnixUser message failed");
3105 if (!check_get_connection_unix_process_id (context, baz))
3106 _dbus_assert_not_reached ("GetConnectionUnixProcessID message failed");
3108 if (!check_no_leftovers (context))
3110 _dbus_warn ("Messages were left over after setting up initial connections");
3111 _dbus_assert_not_reached ("initial connection setup failed");
3114 check1_try_iterations (context, "create_and_hello",
3115 check_hello_connection);
3117 check2_try_iterations (context, foo, "nonexistent_service_activation",
3118 check_nonexistent_service_activation);
3120 check2_try_iterations (context, foo, "segfault_service_activation",
3121 check_segfault_service_activation);
3123 check2_try_iterations (context, foo, "existent_service_activation",
3124 check_existent_service_activation);
3126 check2_try_iterations (context, foo, "nonexistent_service_auto_activation",
3127 check_nonexistent_service_auto_activation);
3129 check2_try_iterations (context, foo, "segfault_service_auto_activation",
3130 check_segfault_service_auto_activation);
3133 /* Note: need to resolve some issues with the testing code in order to run
3134 * this in oom (handle that we sometimes don't get replies back from the bus
3135 * when oom happens, without blocking the test).
3137 check2_try_iterations (context, foo, "existent_service_auto_activation",
3138 check_existent_service_auto_activation);
3141 if (!check_existent_service_auto_activation (context, foo))
3142 _dbus_assert_not_reached ("existent service auto activation failed");
3144 _dbus_verbose ("Disconnecting foo, bar, and baz\n");
3146 kill_client_connection_unchecked (foo);
3147 kill_client_connection_unchecked (bar);
3148 kill_client_connection_unchecked (baz);
3150 bus_context_unref (context);
3156 bus_dispatch_sha1_test (const DBusString *test_data_dir)
3158 BusContext *context;
3159 DBusConnection *foo;
3162 dbus_error_init (&error);
3164 /* Test SHA1 authentication */
3165 _dbus_verbose ("Testing SHA1 context\n");
3167 context = bus_context_new_test (test_data_dir,
3168 "valid-config-files/debug-allow-all-sha1.conf");
3169 if (context == NULL)
3172 foo = dbus_connection_open ("debug-pipe:name=test-server", &error);
3174 _dbus_assert_not_reached ("could not alloc connection");
3176 if (!bus_setup_debug_client (foo))
3177 _dbus_assert_not_reached ("could not set up connection");
3179 if (!check_hello_message (context, foo))
3180 _dbus_assert_not_reached ("hello message failed");
3182 if (!check_add_match_all (context, foo))
3183 _dbus_assert_not_reached ("addmatch message failed");
3185 if (!check_no_leftovers (context))
3187 _dbus_warn ("Messages were left over after setting up initial SHA-1 connection\n");
3188 _dbus_assert_not_reached ("initial connection setup failed");
3191 check1_try_iterations (context, "create_and_hello_sha1",
3192 check_hello_connection);
3194 kill_client_connection_unchecked (foo);
3196 bus_context_unref (context);
3201 #endif /* DBUS_BUILD_TESTS */