<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> <title>dispatch.c Source File</title> <link href="doxygen.css" rel="stylesheet" type="text/css"> </head><body> <!-- Generated by Doxygen 1.2.15 --> <center> <a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="modules.html">Modules</a> <a class="qindex" href="annotated.html">Data Structures</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Data Fields</a> <a class="qindex" href="pages.html">Related Pages</a> </center> <hr><h1>dispatch.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font> 00002 <font class="comment">/* dispatch.c Message dispatcher</font> 00003 <font class="comment"> *</font> 00004 <font class="comment"> * Copyright (C) 2003 CodeFactory AB</font> 00005 <font class="comment"> * Copyright (C) 2003 Red Hat, Inc.</font> 00006 <font class="comment"> *</font> 00007 <font class="comment"> * Licensed under the Academic Free License version 1.2</font> 00008 <font class="comment"> * </font> 00009 <font class="comment"> * This program is free software; you can redistribute it and/or modify</font> 00010 <font class="comment"> * it under the terms of the GNU General Public License as published by</font> 00011 <font class="comment"> * the Free Software Foundation; either version 2 of the License, or</font> 00012 <font class="comment"> * (at your option) any later version.</font> 00013 <font class="comment"> *</font> 00014 <font class="comment"> * This program is distributed in the hope that it will be useful,</font> 00015 <font class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</font> 00016 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</font> 00017 <font class="comment"> * GNU General Public License for more details.</font> 00018 <font class="comment"> * </font> 00019 <font class="comment"> * You should have received a copy of the GNU General Public License</font> 00020 <font class="comment"> * along with this program; if not, write to the Free Software</font> 00021 <font class="comment"> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</font> 00022 <font class="comment"> *</font> 00023 <font class="comment"> */</font> 00024 00025 <font class="preprocessor">#include "dispatch.h"</font> 00026 <font class="preprocessor">#include "connection.h"</font> 00027 <font class="preprocessor">#include "driver.h"</font> 00028 <font class="preprocessor">#include "services.h"</font> 00029 <font class="preprocessor">#include "utils.h"</font> 00030 <font class="preprocessor">#include "bus.h"</font> 00031 <font class="preprocessor">#include "signals.h"</font> 00032 <font class="preprocessor">#include "test.h"</font> 00033 <font class="preprocessor">#include <dbus/dbus-internals.h></font> 00034 <font class="preprocessor">#include <string.h></font> 00035 00036 <font class="keyword">static</font> dbus_bool_t 00037 send_one_message (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 00038 BusContext *context, 00039 <a class="code" href="structDBusConnection.html">DBusConnection</a> *sender, 00040 <a class="code" href="structDBusConnection.html">DBusConnection</a> *addressed_recipient, 00041 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message, 00042 BusTransaction *transaction, 00043 <a class="code" href="structDBusError.html">DBusError</a> *error) 00044 { 00045 <font class="keywordflow">if</font> (!bus_context_check_security_policy (context, 00046 sender, 00047 addressed_recipient, 00048 connection, 00049 message, 00050 NULL)) 00051 <font class="keywordflow">return</font> TRUE; <font class="comment">/* silently don't send it */</font> 00052 00053 <font class="keywordflow">if</font> (!bus_transaction_send (transaction, 00054 connection, 00055 message)) 00056 { 00057 BUS_SET_OOM (error); 00058 <font class="keywordflow">return</font> FALSE; 00059 } 00060 00061 <font class="keywordflow">return</font> TRUE; 00062 } 00063 00064 dbus_bool_t 00065 bus_dispatch_matches (BusTransaction *transaction, 00066 <a class="code" href="structDBusConnection.html">DBusConnection</a> *sender, 00067 <a class="code" href="structDBusConnection.html">DBusConnection</a> *addressed_recipient, 00068 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message, 00069 <a class="code" href="structDBusError.html">DBusError</a> *error) 00070 { 00071 <a class="code" href="structDBusError.html">DBusError</a> tmp_error; 00072 BusConnections *connections; 00073 <a class="code" href="structDBusList.html">DBusList</a> *recipients; 00074 BusMatchmaker *matchmaker; 00075 <a class="code" href="structDBusList.html">DBusList</a> *link; 00076 BusContext *context; 00077 00078 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00079 00080 <font class="comment">/* sender and recipient can both be NULL for the bus driver,</font> 00081 <font class="comment"> * or for signals with no particular recipient</font> 00082 <font class="comment"> */</font> 00083 00084 _dbus_assert (sender == NULL || bus_connection_is_active (sender)); 00085 _dbus_assert (dbus_message_get_sender (message) != NULL); 00086 00087 connections = bus_transaction_get_connections (transaction); 00088 00089 dbus_error_init (&tmp_error); 00090 context = bus_transaction_get_context (transaction); 00091 matchmaker = bus_context_get_matchmaker (context); 00092 00093 recipients = NULL; 00094 <font class="keywordflow">if</font> (!bus_matchmaker_get_recipients (matchmaker, 00095 bus_context_get_connections (context), 00096 sender, addressed_recipient, message, 00097 &recipients)) 00098 { 00099 BUS_SET_OOM (error); 00100 <font class="keywordflow">return</font> FALSE; 00101 } 00102 00103 link = _dbus_list_get_first_link (&recipients); 00104 <font class="keywordflow">while</font> (link != NULL) 00105 { 00106 <a class="code" href="structDBusConnection.html">DBusConnection</a> *dest; 00107 00108 dest = link-><a class="code" href="structDBusList.html#m2">data</a>; 00109 00110 <font class="keywordflow">if</font> (!send_one_message (dest, context, sender, addressed_recipient, 00111 message, transaction, &tmp_error)) 00112 <font class="keywordflow">break</font>; 00113 00114 link = _dbus_list_get_next_link (&recipients, link); 00115 } 00116 00117 _dbus_list_clear (&recipients); 00118 00119 <font class="keywordflow">if</font> (dbus_error_is_set (&tmp_error)) 00120 { 00121 dbus_move_error (&tmp_error, error); 00122 <font class="keywordflow">return</font> FALSE; 00123 } 00124 <font class="keywordflow">else</font> 00125 <font class="keywordflow">return</font> TRUE; 00126 } 00127 00128 <font class="keyword">static</font> DBusHandlerResult 00129 bus_dispatch (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 00130 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message) 00131 { 00132 <font class="keyword">const</font> <font class="keywordtype">char</font> *sender, *service_name; 00133 <a class="code" href="structDBusError.html">DBusError</a> error; 00134 BusTransaction *transaction; 00135 BusContext *context; 00136 DBusHandlerResult result; 00137 <a class="code" href="structDBusConnection.html">DBusConnection</a> *addressed_recipient; 00138 00139 result = DBUS_HANDLER_RESULT_HANDLED; 00140 00141 transaction = NULL; 00142 addressed_recipient = NULL; 00143 dbus_error_init (&error); 00144 00145 context = bus_connection_get_context (connection); 00146 _dbus_assert (context != NULL); 00147 00148 <font class="comment">/* If we can't even allocate an OOM error, we just go to sleep</font> 00149 <font class="comment"> * until we can.</font> 00150 <font class="comment"> */</font> 00151 <font class="keywordflow">while</font> (!bus_connection_preallocate_oom_error (connection)) 00152 _dbus_wait_for_memory (); 00153 00154 <font class="comment">/* Ref connection in case we disconnect it at some point in here */</font> 00155 dbus_connection_ref (connection); 00156 00157 service_name = dbus_message_get_destination (message); 00158 00159 <font class="preprocessor">#ifdef DBUS_ENABLE_VERBOSE_MODE</font> 00160 <font class="preprocessor"></font> { 00161 <font class="keyword">const</font> <font class="keywordtype">char</font> *interface_name, *member_name, *error_name; 00162 00163 interface_name = dbus_message_get_interface (message); 00164 member_name = dbus_message_get_member (message); 00165 error_name = dbus_message_get_error_name (message); 00166 00167 _dbus_verbose (<font class="stringliteral">"DISPATCH: %s %s %s to %s\n"</font>, 00168 interface_name ? interface_name : <font class="stringliteral">"(no interface)"</font>, 00169 member_name ? member_name : <font class="stringliteral">"(no member)"</font>, 00170 error_name ? error_name : <font class="stringliteral">"(no error name)"</font>, 00171 service_name ? service_name : <font class="stringliteral">"peer"</font>); 00172 } 00173 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_ENABLE_VERBOSE_MODE */</font> 00174 00175 <font class="comment">/* If service_name is NULL, if it's a signal we send it to all</font> 00176 <font class="comment"> * connections with a match rule. If it's not a signal, it goes to</font> 00177 <font class="comment"> * the bus daemon but doesn't go "on the bus"; e.g. a peer-to-peer</font> 00178 <font class="comment"> * ping. Handle these immediately, especially disconnection</font> 00179 <font class="comment"> * messages. There are no security policy checks on these.</font> 00180 <font class="comment"> */</font> 00181 <font class="keywordflow">if</font> (service_name == NULL) 00182 { 00183 <font class="keywordflow">if</font> (dbus_message_is_signal (message, 00184 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, 00185 <font class="stringliteral">"Disconnected"</font>)) 00186 { 00187 bus_connection_disconnected (connection); 00188 <font class="keywordflow">goto</font> out; 00189 } 00190 00191 <font class="keywordflow">if</font> (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL) 00192 { 00193 <font class="comment">/* DBusConnection also handles some of these automatically, we leave</font> 00194 <font class="comment"> * it to do so.</font> 00195 <font class="comment"> */</font> 00196 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 00197 <font class="keywordflow">goto</font> out; 00198 } 00199 } 00200 00201 <font class="comment">/* Create our transaction */</font> 00202 transaction = bus_transaction_new (context); 00203 <font class="keywordflow">if</font> (transaction == NULL) 00204 { 00205 BUS_SET_OOM (&error); 00206 <font class="keywordflow">goto</font> out; 00207 } 00208 00209 <font class="comment">/* Assign a sender to the message */</font> 00210 <font class="keywordflow">if</font> (bus_connection_is_active (connection)) 00211 { 00212 sender = bus_connection_get_name (connection); 00213 _dbus_assert (sender != NULL); 00214 00215 <font class="keywordflow">if</font> (!dbus_message_set_sender (message, sender)) 00216 { 00217 BUS_SET_OOM (&error); 00218 <font class="keywordflow">goto</font> out; 00219 } 00220 00221 <font class="comment">/* We need to refetch the service name here, because</font> 00222 <font class="comment"> * dbus_message_set_sender can cause the header to be</font> 00223 <font class="comment"> * reallocated, and thus the service_name pointer will become</font> 00224 <font class="comment"> * invalid.</font> 00225 <font class="comment"> */</font> 00226 service_name = dbus_message_get_destination (message); 00227 } 00228 00229 <font class="keywordflow">if</font> (service_name && 00230 strcmp (service_name, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS) == 0) <font class="comment">/* to bus driver */</font> 00231 { 00232 <font class="keywordflow">if</font> (!bus_context_check_security_policy (context, 00233 connection, NULL, NULL, message, &error)) 00234 { 00235 _dbus_verbose (<font class="stringliteral">"Security policy rejected message\n"</font>); 00236 <font class="keywordflow">goto</font> out; 00237 } 00238 00239 _dbus_verbose (<font class="stringliteral">"Giving message to %s\n"</font>, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS); 00240 <font class="keywordflow">if</font> (!bus_driver_handle_message (connection, transaction, message, &error)) 00241 <font class="keywordflow">goto</font> out; 00242 } 00243 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (!bus_connection_is_active (connection)) <font class="comment">/* clients must talk to bus driver first */</font> 00244 { 00245 _dbus_verbose (<font class="stringliteral">"Received message from non-registered client. Disconnecting.\n"</font>); 00246 dbus_connection_disconnect (connection); 00247 <font class="keywordflow">goto</font> out; 00248 } 00249 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (service_name != NULL) <font class="comment">/* route to named service */</font> 00250 { 00251 <a class="code" href="structDBusString.html">DBusString</a> service_string; 00252 BusService *service; 00253 BusRegistry *registry; 00254 00255 _dbus_assert (service_name != NULL); 00256 00257 registry = bus_connection_get_registry (connection); 00258 00259 _dbus_string_init_const (&service_string, service_name); 00260 service = bus_registry_lookup (registry, &service_string); 00261 00262 <font class="keywordflow">if</font> (service == NULL) 00263 { 00264 dbus_set_error (&error, 00265 DBUS_ERROR_SERVICE_DOES_NOT_EXIST, 00266 <font class="stringliteral">"Service \"%s\" does not exist"</font>, 00267 service_name); 00268 <font class="keywordflow">goto</font> out; 00269 } 00270 <font class="keywordflow">else</font> 00271 { 00272 addressed_recipient = bus_service_get_primary_owner (service); 00273 _dbus_assert (addressed_recipient != NULL); 00274 00275 <font class="keywordflow">if</font> (!bus_context_check_security_policy (context, 00276 connection, addressed_recipient, 00277 addressed_recipient, 00278 message, &error)) 00279 <font class="keywordflow">goto</font> out; 00280 00281 <font class="comment">/* Dispatch the message */</font> 00282 <font class="keywordflow">if</font> (!bus_transaction_send (transaction, addressed_recipient, message)) 00283 { 00284 BUS_SET_OOM (&error); 00285 <font class="keywordflow">goto</font> out; 00286 } 00287 } 00288 } 00289 00290 <font class="comment">/* Now match the messages against any match rules, which will send</font> 00291 <font class="comment"> * out signals and such. addressed_recipient may == NULL.</font> 00292 <font class="comment"> */</font> 00293 <font class="keywordflow">if</font> (!bus_dispatch_matches (transaction, connection, addressed_recipient, message, &error)) 00294 <font class="keywordflow">goto</font> out; 00295 00296 out: 00297 <font class="keywordflow">if</font> (dbus_error_is_set (&error)) 00298 { 00299 <font class="keywordflow">if</font> (!dbus_connection_get_is_connected (connection)) 00300 { 00301 <font class="comment">/* If we disconnected it, we won't bother to send it any error</font> 00302 <font class="comment"> * messages.</font> 00303 <font class="comment"> */</font> 00304 _dbus_verbose (<font class="stringliteral">"Not sending error to connection we disconnected\n"</font>); 00305 } 00306 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 00307 { 00308 bus_connection_send_oom_error (connection, message); 00309 00310 <font class="comment">/* cancel transaction due to OOM */</font> 00311 <font class="keywordflow">if</font> (transaction != NULL) 00312 { 00313 bus_transaction_cancel_and_free (transaction); 00314 transaction = NULL; 00315 } 00316 } 00317 <font class="keywordflow">else</font> 00318 { 00319 <font class="comment">/* Try to send the real error, if no mem to do that, send</font> 00320 <font class="comment"> * the OOM error</font> 00321 <font class="comment"> */</font> 00322 _dbus_assert (transaction != NULL); 00323 00324 <font class="keywordflow">if</font> (!bus_transaction_send_error_reply (transaction, connection, 00325 &error, message)) 00326 { 00327 bus_connection_send_oom_error (connection, message); 00328 00329 <font class="comment">/* cancel transaction due to OOM */</font> 00330 <font class="keywordflow">if</font> (transaction != NULL) 00331 { 00332 bus_transaction_cancel_and_free (transaction); 00333 transaction = NULL; 00334 } 00335 } 00336 } 00337 00338 dbus_error_free (&error); 00339 } 00340 00341 <font class="keywordflow">if</font> (transaction != NULL) 00342 { 00343 bus_transaction_execute_and_free (transaction); 00344 } 00345 00346 dbus_connection_unref (connection); 00347 00348 <font class="keywordflow">return</font> result; 00349 } 00350 00351 <font class="keyword">static</font> DBusHandlerResult 00352 bus_dispatch_message_filter (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 00353 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message, 00354 <font class="keywordtype">void</font> *user_data) 00355 { 00356 <font class="keywordflow">return</font> bus_dispatch (connection, message); 00357 } 00358 00359 dbus_bool_t 00360 bus_dispatch_add_connection (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection) 00361 { 00362 <font class="keywordflow">if</font> (!dbus_connection_add_filter (connection, 00363 bus_dispatch_message_filter, 00364 NULL, NULL)) 00365 <font class="keywordflow">return</font> FALSE; 00366 00367 <font class="keywordflow">return</font> TRUE; 00368 } 00369 00370 <font class="keywordtype">void</font> 00371 bus_dispatch_remove_connection (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection) 00372 { 00373 <font class="comment">/* Here we tell the bus driver that we want to get off. */</font> 00374 bus_driver_remove_connection (connection); 00375 00376 dbus_connection_remove_filter (connection, 00377 bus_dispatch_message_filter, 00378 NULL); 00379 } 00380 00381 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font> 00382 <font class="preprocessor"></font> 00383 <font class="keyword">typedef</font> dbus_bool_t (* Check1Func) (BusContext *context); 00384 <font class="keyword">typedef</font> dbus_bool_t (* Check2Func) (BusContext *context, 00385 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection); 00386 00387 <font class="keyword">static</font> dbus_bool_t check_no_leftovers (BusContext *context); 00388 00389 <font class="keyword">static</font> <font class="keywordtype">void</font> 00390 block_connection_until_message_from_bus (BusContext *context, 00391 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection) 00392 { 00393 <font class="keywordflow">while</font> (dbus_connection_get_dispatch_status (connection) == 00394 DBUS_DISPATCH_COMPLETE && 00395 dbus_connection_get_is_connected (connection)) 00396 { 00397 bus_test_run_bus_loop (context, TRUE); 00398 bus_test_run_clients_loop (FALSE); 00399 } 00400 } 00401 00402 <font class="comment">/* compensate for fact that pop_message() can return #NULL due to OOM */</font> 00403 <font class="keyword">static</font> <a class="code" href="structDBusMessage.html">DBusMessage</a>* 00404 pop_message_waiting_for_memory (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection) 00405 { 00406 <font class="keywordflow">while</font> (dbus_connection_get_dispatch_status (connection) == 00407 DBUS_DISPATCH_NEED_MEMORY) 00408 _dbus_wait_for_memory (); 00409 00410 <font class="keywordflow">return</font> dbus_connection_pop_message (connection); 00411 } 00412 00413 <font class="keyword">static</font> <font class="keywordtype">void</font> 00414 warn_unexpected_real (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 00415 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message, 00416 <font class="keyword">const</font> <font class="keywordtype">char</font> *expected, 00417 <font class="keyword">const</font> <font class="keywordtype">char</font> *function, 00418 <font class="keywordtype">int</font> line) 00419 { 00420 _dbus_warn (<font class="stringliteral">"%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s\n"</font>, 00421 function, line, 00422 dbus_message_get_interface (message) ? 00423 dbus_message_get_interface (message) : "(unset)", 00424 dbus_message_get_member (message) ? 00425 dbus_message_get_member (message) : "(unset)", 00426 dbus_message_get_error_name (message) ? 00427 dbus_message_get_error_name (message) : "(unset)", 00428 connection, 00429 expected); 00430 } 00431 00432 <font class="preprocessor">#define warn_unexpected(connection, message, expected) \</font> 00433 <font class="preprocessor"> warn_unexpected_real (connection, message, expected, _DBUS_FUNCTION_NAME, __LINE__)</font> 00434 <font class="preprocessor"></font> 00435 <font class="keyword">static</font> <font class="keywordtype">void</font> 00436 verbose_message_received (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 00437 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message) 00438 { 00439 _dbus_verbose (<font class="stringliteral">"Received message interface \"%s\" member \"%s\" error name \"%s\" on %p\n"</font>, 00440 dbus_message_get_interface (message) ? 00441 dbus_message_get_interface (message) : "(unset)", 00442 dbus_message_get_member (message) ? 00443 dbus_message_get_member (message) : "(unset)", 00444 dbus_message_get_error_name (message) ? 00445 dbus_message_get_error_name (message) : "(unset)", 00446 connection); 00447 } 00448 00449 <font class="keyword">typedef</font> <font class="keyword">struct</font> 00450 <font class="keyword"></font>{ 00451 <font class="keyword">const</font> <font class="keywordtype">char</font> *expected_service_name; 00452 dbus_bool_t failed; 00453 } CheckServiceDeletedData; 00454 00455 <font class="keyword">static</font> dbus_bool_t 00456 check_service_deleted_foreach (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 00457 <font class="keywordtype">void</font> *data) 00458 { 00459 CheckServiceDeletedData *d = data; 00460 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message; 00461 <a class="code" href="structDBusError.html">DBusError</a> error; 00462 <font class="keywordtype">char</font> *service_name; 00463 00464 dbus_error_init (&error); 00465 d->failed = TRUE; 00466 service_name = NULL; 00467 00468 message = pop_message_waiting_for_memory (connection); 00469 <font class="keywordflow">if</font> (message == NULL) 00470 { 00471 _dbus_warn (<font class="stringliteral">"Did not receive a message on %p, expecting %s\n"</font>, 00472 connection, <font class="stringliteral">"ServiceDeleted"</font>); 00473 <font class="keywordflow">goto</font> out; 00474 } 00475 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (!dbus_message_is_signal (message, 00476 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, 00477 <font class="stringliteral">"ServiceDeleted"</font>)) 00478 { 00479 warn_unexpected (connection, message, <font class="stringliteral">"ServiceDeleted"</font>); 00480 00481 <font class="keywordflow">goto</font> out; 00482 } 00483 <font class="keywordflow">else</font> 00484 { 00485 <font class="keywordflow">if</font> (!dbus_message_get_args (message, &error, 00486 DBUS_TYPE_STRING, &service_name, 00487 DBUS_TYPE_INVALID)) 00488 { 00489 <font class="keywordflow">if</font> (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 00490 { 00491 _dbus_verbose (<font class="stringliteral">"no memory to get service name arg\n"</font>); 00492 } 00493 <font class="keywordflow">else</font> 00494 { 00495 _dbus_assert (dbus_error_is_set (&error)); 00496 _dbus_warn (<font class="stringliteral">"Did not get the expected single string argument\n"</font>); 00497 <font class="keywordflow">goto</font> out; 00498 } 00499 } 00500 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (service_name, d->expected_service_name) != 0) 00501 { 00502 _dbus_warn (<font class="stringliteral">"expected deletion of service %s, got deletion of %s\n"</font>, 00503 d->expected_service_name, 00504 service_name); 00505 <font class="keywordflow">goto</font> out; 00506 } 00507 } 00508 00509 d->failed = FALSE; 00510 00511 out: 00512 dbus_free (service_name); 00513 dbus_error_free (&error); 00514 00515 <font class="keywordflow">if</font> (message) 00516 dbus_message_unref (message); 00517 00518 <font class="keywordflow">return</font> !d->failed; 00519 } 00520 00521 <font class="keyword">static</font> <font class="keywordtype">void</font> 00522 kill_client_connection (BusContext *context, 00523 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection) 00524 { 00525 <font class="keywordtype">char</font> *base_service; 00526 <font class="keyword">const</font> <font class="keywordtype">char</font> *s; 00527 CheckServiceDeletedData csdd; 00528 00529 _dbus_verbose (<font class="stringliteral">"killing connection %p\n"</font>, connection); 00530 00531 s = dbus_bus_get_base_service (connection); 00532 _dbus_assert (s != NULL); 00533 00534 <font class="keywordflow">while</font> ((base_service = _dbus_strdup (s)) == NULL) 00535 _dbus_wait_for_memory (); 00536 00537 dbus_connection_ref (connection); 00538 00539 <font class="comment">/* kick in the disconnect handler that unrefs the connection */</font> 00540 dbus_connection_disconnect (connection); 00541 00542 bus_test_run_everything (context); 00543 00544 _dbus_assert (bus_test_client_listed (connection)); 00545 00546 <font class="comment">/* Run disconnect handler in test.c */</font> 00547 <font class="keywordflow">if</font> (bus_connection_dispatch_one_message (connection)) 00548 _dbus_assert_not_reached (<font class="stringliteral">"something received on connection being killed other than the disconnect"</font>); 00549 00550 _dbus_assert (!dbus_connection_get_is_connected (connection)); 00551 dbus_connection_unref (connection); 00552 connection = NULL; 00553 _dbus_assert (!bus_test_client_listed (connection)); 00554 00555 csdd.expected_service_name = base_service; 00556 csdd.failed = FALSE; 00557 00558 bus_test_clients_foreach (check_service_deleted_foreach, 00559 &csdd); 00560 00561 dbus_free (base_service); 00562 00563 <font class="keywordflow">if</font> (csdd.failed) 00564 _dbus_assert_not_reached (<font class="stringliteral">"didn't get the expected ServiceDeleted messages"</font>); 00565 00566 <font class="keywordflow">if</font> (!check_no_leftovers (context)) 00567 _dbus_assert_not_reached (<font class="stringliteral">"stuff left in message queues after disconnecting a client"</font>); 00568 } 00569 00570 <font class="keyword">static</font> <font class="keywordtype">void</font> 00571 kill_client_connection_unchecked (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection) 00572 { 00573 <font class="comment">/* This kills the connection without expecting it to affect</font> 00574 <font class="comment"> * the rest of the bus.</font> 00575 <font class="comment"> */</font> 00576 _dbus_verbose (<font class="stringliteral">"Unchecked kill of connection %p\n"</font>, connection); 00577 00578 dbus_connection_ref (connection); 00579 dbus_connection_disconnect (connection); 00580 <font class="comment">/* dispatching disconnect handler will unref once */</font> 00581 <font class="keywordflow">if</font> (bus_connection_dispatch_one_message (connection)) 00582 _dbus_assert_not_reached (<font class="stringliteral">"message other than disconnect dispatched after failure to register"</font>); 00583 00584 _dbus_assert (!bus_test_client_listed (connection)); 00585 dbus_connection_unref (connection); 00586 } 00587 00588 <font class="keyword">typedef</font> <font class="keyword">struct</font> 00589 <font class="keyword"></font>{ 00590 dbus_bool_t failed; 00591 } CheckNoMessagesData; 00592 00593 <font class="keyword">static</font> dbus_bool_t 00594 check_no_messages_foreach (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 00595 <font class="keywordtype">void</font> *data) 00596 { 00597 CheckNoMessagesData *d = data; 00598 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message; 00599 00600 message = pop_message_waiting_for_memory (connection); 00601 <font class="keywordflow">if</font> (message != NULL) 00602 { 00603 warn_unexpected (connection, message, <font class="stringliteral">"no messages"</font>); 00604 00605 d->failed = TRUE; 00606 } 00607 00608 <font class="keywordflow">if</font> (message) 00609 dbus_message_unref (message); 00610 <font class="keywordflow">return</font> !d->failed; 00611 } 00612 00613 <font class="keyword">typedef</font> <font class="keyword">struct</font> 00614 <font class="keyword"></font>{ 00615 <a class="code" href="structDBusConnection.html">DBusConnection</a> *skip_connection; 00616 <font class="keyword">const</font> <font class="keywordtype">char</font> *expected_service_name; 00617 dbus_bool_t failed; 00618 } CheckServiceCreatedData; 00619 00620 <font class="keyword">static</font> dbus_bool_t 00621 check_service_created_foreach (<a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 00622 <font class="keywordtype">void</font> *data) 00623 { 00624 CheckServiceCreatedData *d = data; 00625 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message; 00626 <a class="code" href="structDBusError.html">DBusError</a> error; 00627 <font class="keywordtype">char</font> *service_name; 00628 00629 <font class="keywordflow">if</font> (connection == d->skip_connection) 00630 <font class="keywordflow">return</font> TRUE; 00631 00632 dbus_error_init (&error); 00633 d->failed = TRUE; 00634 service_name = NULL; 00635 00636 message = pop_message_waiting_for_memory (connection); 00637 <font class="keywordflow">if</font> (message == NULL) 00638 { 00639 _dbus_warn (<font class="stringliteral">"Did not receive a message on %p, expecting %s\n"</font>, 00640 connection, <font class="stringliteral">"ServiceCreated"</font>); 00641 <font class="keywordflow">goto</font> out; 00642 } 00643 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (!dbus_message_is_signal (message, 00644 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, 00645 <font class="stringliteral">"ServiceCreated"</font>)) 00646 { 00647 warn_unexpected (connection, message, <font class="stringliteral">"ServiceCreated"</font>); 00648 <font class="keywordflow">goto</font> out; 00649 } 00650 <font class="keywordflow">else</font> 00651 { 00652 <font class="keywordflow">if</font> (!dbus_message_get_args (message, &error, 00653 DBUS_TYPE_STRING, &service_name, 00654 DBUS_TYPE_INVALID)) 00655 { 00656 <font class="keywordflow">if</font> (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 00657 { 00658 _dbus_verbose (<font class="stringliteral">"no memory to get service name arg\n"</font>); 00659 } 00660 <font class="keywordflow">else</font> 00661 { 00662 _dbus_assert (dbus_error_is_set (&error)); 00663 _dbus_warn (<font class="stringliteral">"Did not get the expected single string argument\n"</font>); 00664 <font class="keywordflow">goto</font> out; 00665 } 00666 } 00667 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (strcmp (service_name, d->expected_service_name) != 0) 00668 { 00669 _dbus_warn (<font class="stringliteral">"expected creation of service %s, got creation of %s\n"</font>, 00670 d->expected_service_name, 00671 service_name); 00672 <font class="keywordflow">goto</font> out; 00673 } 00674 } 00675 00676 d->failed = FALSE; 00677 00678 out: 00679 dbus_free (service_name); 00680 dbus_error_free (&error); 00681 00682 <font class="keywordflow">if</font> (message) 00683 dbus_message_unref (message); 00684 00685 <font class="keywordflow">return</font> !d->failed; 00686 } 00687 00688 <font class="keyword">static</font> dbus_bool_t 00689 check_no_leftovers (BusContext *context) 00690 { 00691 CheckNoMessagesData nmd; 00692 00693 nmd.failed = FALSE; 00694 bus_test_clients_foreach (check_no_messages_foreach, 00695 &nmd); 00696 00697 <font class="keywordflow">if</font> (nmd.failed) 00698 <font class="keywordflow">return</font> FALSE; 00699 <font class="keywordflow">else</font> 00700 <font class="keywordflow">return</font> TRUE; 00701 } 00702 00703 <font class="comment">/* returns TRUE if the correct thing happens,</font> 00704 <font class="comment"> * but the correct thing may include OOM errors.</font> 00705 <font class="comment"> */</font> 00706 <font class="keyword">static</font> dbus_bool_t 00707 check_hello_message (BusContext *context, 00708 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection) 00709 { 00710 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message; 00711 dbus_uint32_t serial; 00712 dbus_bool_t retval; 00713 <a class="code" href="structDBusError.html">DBusError</a> error; 00714 <font class="keywordtype">char</font> *name; 00715 <font class="keywordtype">char</font> *acquired; 00716 00717 retval = FALSE; 00718 dbus_error_init (&error); 00719 name = NULL; 00720 acquired = NULL; 00721 message = NULL; 00722 00723 _dbus_verbose (<font class="stringliteral">"check_hello_message for %p\n"</font>, connection); 00724 00725 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS, 00726 DBUS_PATH_ORG_FREEDESKTOP_DBUS, 00727 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, 00728 <font class="stringliteral">"Hello"</font>); 00729 00730 <font class="keywordflow">if</font> (message == NULL) 00731 <font class="keywordflow">return</font> TRUE; 00732 00733 <font class="keywordflow">if</font> (!dbus_connection_send (connection, message, &serial)) 00734 { 00735 dbus_message_unref (message); 00736 <font class="keywordflow">return</font> TRUE; 00737 } 00738 00739 dbus_message_unref (message); 00740 message = NULL; 00741 00742 <font class="comment">/* send our message */</font> 00743 bus_test_run_clients_loop (TRUE); 00744 00745 dbus_connection_ref (connection); <font class="comment">/* because we may get disconnected */</font> 00746 block_connection_until_message_from_bus (context, connection); 00747 00748 <font class="keywordflow">if</font> (!dbus_connection_get_is_connected (connection)) 00749 { 00750 _dbus_verbose (<font class="stringliteral">"connection was disconnected\n"</font>); 00751 00752 dbus_connection_unref (connection); 00753 00754 <font class="keywordflow">return</font> TRUE; 00755 } 00756 00757 dbus_connection_unref (connection); 00758 00759 message = pop_message_waiting_for_memory (connection); 00760 <font class="keywordflow">if</font> (message == NULL) 00761 { 00762 _dbus_warn (<font class="stringliteral">"Did not receive a reply to %s %d on %p\n"</font>, 00763 <font class="stringliteral">"Hello"</font>, serial, connection); 00764 <font class="keywordflow">goto</font> out; 00765 } 00766 00767 verbose_message_received (connection, message); 00768 00769 <font class="keywordflow">if</font> (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS)) 00770 { 00771 _dbus_warn (<font class="stringliteral">"Message has wrong sender %s\n"</font>, 00772 dbus_message_get_sender (message) ? 00773 dbus_message_get_sender (message) : "(none)"); 00774 <font class="keywordflow">goto</font> out; 00775 } 00776 00777 <font class="keywordflow">if</font> (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 00778 { 00779 <font class="keywordflow">if</font> (dbus_message_is_error (message, 00780 DBUS_ERROR_NO_MEMORY)) 00781 { 00782 ; <font class="comment">/* good, this is a valid response */</font> 00783 } 00784 <font class="keywordflow">else</font> 00785 { 00786 warn_unexpected (connection, message, <font class="stringliteral">"not this error"</font>); 00787 00788 <font class="keywordflow">goto</font> out; 00789 } 00790 } 00791 <font class="keywordflow">else</font> 00792 { 00793 CheckServiceCreatedData scd; 00794 00795 <font class="keywordflow">if</font> (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN) 00796 { 00797 ; <font class="comment">/* good, expected */</font> 00798 } 00799 <font class="keywordflow">else</font> 00800 { 00801 warn_unexpected (connection, message, <font class="stringliteral">"method return for Hello"</font>); 00802 00803 <font class="keywordflow">goto</font> out; 00804 } 00805 00806 retry_get_hello_name: 00807 <font class="keywordflow">if</font> (!dbus_message_get_args (message, &error, 00808 DBUS_TYPE_STRING, &name, 00809 DBUS_TYPE_INVALID)) 00810 { 00811 <font class="keywordflow">if</font> (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 00812 { 00813 _dbus_verbose (<font class="stringliteral">"no memory to get service name arg from hello\n"</font>); 00814 dbus_error_free (&error); 00815 _dbus_wait_for_memory (); 00816 <font class="keywordflow">goto</font> retry_get_hello_name; 00817 } 00818 <font class="keywordflow">else</font> 00819 { 00820 _dbus_assert (dbus_error_is_set (&error)); 00821 _dbus_warn (<font class="stringliteral">"Did not get the expected single string argument to hello\n"</font>); 00822 <font class="keywordflow">goto</font> out; 00823 } 00824 } 00825 00826 _dbus_verbose (<font class="stringliteral">"Got hello name: %s\n"</font>, name); 00827 00828 <font class="keywordflow">while</font> (!dbus_bus_set_base_service (connection, name)) 00829 _dbus_wait_for_memory (); 00830 00831 scd.skip_connection = connection; <font class="comment">/* we haven't done AddMatch so won't get it ourselves */</font> 00832 scd.failed = FALSE; 00833 scd.expected_service_name = name; 00834 bus_test_clients_foreach (check_service_created_foreach, 00835 &scd); 00836 00837 <font class="keywordflow">if</font> (scd.failed) 00838 <font class="keywordflow">goto</font> out; 00839 00840 <font class="comment">/* Client should also have gotten ServiceAcquired */</font> 00841 dbus_message_unref (message); 00842 message = pop_message_waiting_for_memory (connection); 00843 <font class="keywordflow">if</font> (message == NULL) 00844 { 00845 _dbus_warn (<font class="stringliteral">"Expecting %s, got nothing\n"</font>, 00846 <font class="stringliteral">"ServiceAcquired"</font>); 00847 <font class="keywordflow">goto</font> out; 00848 } 00849 00850 retry_get_acquired_name: 00851 <font class="keywordflow">if</font> (!dbus_message_get_args (message, &error, 00852 DBUS_TYPE_STRING, &acquired, 00853 DBUS_TYPE_INVALID)) 00854 { 00855 <font class="keywordflow">if</font> (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 00856 { 00857 _dbus_verbose (<font class="stringliteral">"no memory to get service name arg from acquired\n"</font>); 00858 dbus_error_free (&error); 00859 _dbus_wait_for_memory (); 00860 <font class="keywordflow">goto</font> retry_get_acquired_name; 00861 } 00862 <font class="keywordflow">else</font> 00863 { 00864 _dbus_assert (dbus_error_is_set (&error)); 00865 _dbus_warn (<font class="stringliteral">"Did not get the expected single string argument to ServiceAcquired\n"</font>); 00866 <font class="keywordflow">goto</font> out; 00867 } 00868 } 00869 00870 _dbus_verbose (<font class="stringliteral">"Got acquired name: %s\n"</font>, acquired); 00871 00872 <font class="keywordflow">if</font> (strcmp (acquired, name) != 0) 00873 { 00874 _dbus_warn (<font class="stringliteral">"Acquired name is %s but expected %s\n"</font>, 00875 acquired, name); 00876 <font class="keywordflow">goto</font> out; 00877 } 00878 } 00879 00880 <font class="keywordflow">if</font> (!check_no_leftovers (context)) 00881 <font class="keywordflow">goto</font> out; 00882 00883 retval = TRUE; 00884 00885 out: 00886 dbus_error_free (&error); 00887 00888 dbus_free (name); 00889 dbus_free (acquired); 00890 00891 <font class="keywordflow">if</font> (message) 00892 dbus_message_unref (message); 00893 00894 <font class="keywordflow">return</font> retval; 00895 } 00896 00897 <font class="comment">/* returns TRUE if the correct thing happens,</font> 00898 <font class="comment"> * but the correct thing may include OOM errors.</font> 00899 <font class="comment"> */</font> 00900 <font class="keyword">static</font> dbus_bool_t 00901 check_add_match_all (BusContext *context, 00902 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection) 00903 { 00904 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message; 00905 dbus_bool_t retval; 00906 dbus_uint32_t serial; 00907 <a class="code" href="structDBusError.html">DBusError</a> error; 00908 00909 retval = FALSE; 00910 dbus_error_init (&error); 00911 message = NULL; 00912 00913 _dbus_verbose (<font class="stringliteral">"check_add_match_all for %p\n"</font>, connection); 00914 00915 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS, 00916 DBUS_PATH_ORG_FREEDESKTOP_DBUS, 00917 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, 00918 <font class="stringliteral">"AddMatch"</font>); 00919 00920 <font class="keywordflow">if</font> (message == NULL) 00921 <font class="keywordflow">return</font> TRUE; 00922 00923 <font class="keywordflow">if</font> (!dbus_message_append_args (message, DBUS_TYPE_STRING, <font class="stringliteral">""</font>, <font class="comment">/* FIXME */</font> 00924 DBUS_TYPE_INVALID)) 00925 { 00926 dbus_message_unref (message); 00927 <font class="keywordflow">return</font> TRUE; 00928 } 00929 00930 <font class="keywordflow">if</font> (!dbus_connection_send (connection, message, &serial)) 00931 { 00932 dbus_message_unref (message); 00933 <font class="keywordflow">return</font> TRUE; 00934 } 00935 00936 dbus_message_unref (message); 00937 message = NULL; 00938 00939 <font class="comment">/* send our message */</font> 00940 bus_test_run_clients_loop (TRUE); 00941 00942 dbus_connection_ref (connection); <font class="comment">/* because we may get disconnected */</font> 00943 block_connection_until_message_from_bus (context, connection); 00944 00945 <font class="keywordflow">if</font> (!dbus_connection_get_is_connected (connection)) 00946 { 00947 _dbus_verbose (<font class="stringliteral">"connection was disconnected\n"</font>); 00948 00949 dbus_connection_unref (connection); 00950 00951 <font class="keywordflow">return</font> TRUE; 00952 } 00953 00954 dbus_connection_unref (connection); 00955 00956 message = pop_message_waiting_for_memory (connection); 00957 <font class="keywordflow">if</font> (message == NULL) 00958 { 00959 _dbus_warn (<font class="stringliteral">"Did not receive a reply to %s %d on %p\n"</font>, 00960 <font class="stringliteral">"AddMatch"</font>, serial, connection); 00961 <font class="keywordflow">goto</font> out; 00962 } 00963 00964 verbose_message_received (connection, message); 00965 00966 <font class="keywordflow">if</font> (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS)) 00967 { 00968 _dbus_warn (<font class="stringliteral">"Message has wrong sender %s\n"</font>, 00969 dbus_message_get_sender (message) ? 00970 dbus_message_get_sender (message) : "(none)"); 00971 <font class="keywordflow">goto</font> out; 00972 } 00973 00974 <font class="keywordflow">if</font> (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 00975 { 00976 <font class="keywordflow">if</font> (dbus_message_is_error (message, 00977 DBUS_ERROR_NO_MEMORY)) 00978 { 00979 ; <font class="comment">/* good, this is a valid response */</font> 00980 } 00981 <font class="keywordflow">else</font> 00982 { 00983 warn_unexpected (connection, message, <font class="stringliteral">"not this error"</font>); 00984 00985 <font class="keywordflow">goto</font> out; 00986 } 00987 } 00988 <font class="keywordflow">else</font> 00989 { 00990 <font class="keywordflow">if</font> (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN) 00991 { 00992 ; <font class="comment">/* good, expected */</font> 00993 _dbus_assert (dbus_message_get_reply_serial (message) == serial); 00994 } 00995 <font class="keywordflow">else</font> 00996 { 00997 warn_unexpected (connection, message, <font class="stringliteral">"method return for AddMatch"</font>); 00998 00999 <font class="keywordflow">goto</font> out; 01000 } 01001 } 01002 01003 <font class="keywordflow">if</font> (!check_no_leftovers (context)) 01004 <font class="keywordflow">goto</font> out; 01005 01006 retval = TRUE; 01007 01008 out: 01009 dbus_error_free (&error); 01010 01011 <font class="keywordflow">if</font> (message) 01012 dbus_message_unref (message); 01013 01014 <font class="keywordflow">return</font> retval; 01015 } 01016 01017 <font class="comment">/* returns TRUE if the correct thing happens,</font> 01018 <font class="comment"> * but the correct thing may include OOM errors.</font> 01019 <font class="comment"> */</font> 01020 <font class="keyword">static</font> dbus_bool_t 01021 check_hello_connection (BusContext *context) 01022 { 01023 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection; 01024 <a class="code" href="structDBusError.html">DBusError</a> error; 01025 01026 dbus_error_init (&error); 01027 01028 connection = dbus_connection_open (<font class="stringliteral">"debug-pipe:name=test-server"</font>, &error); 01029 <font class="keywordflow">if</font> (connection == NULL) 01030 { 01031 _DBUS_ASSERT_ERROR_IS_SET (&error); 01032 dbus_error_free (&error); 01033 <font class="keywordflow">return</font> TRUE; 01034 } 01035 01036 <font class="keywordflow">if</font> (!bus_setup_debug_client (connection)) 01037 { 01038 dbus_connection_disconnect (connection); 01039 dbus_connection_unref (connection); 01040 <font class="keywordflow">return</font> TRUE; 01041 } 01042 01043 <font class="keywordflow">if</font> (!check_hello_message (context, connection)) 01044 <font class="keywordflow">return</font> FALSE; 01045 01046 <font class="keywordflow">if</font> (dbus_bus_get_base_service (connection) == NULL) 01047 { 01048 <font class="comment">/* We didn't successfully register, so we can't</font> 01049 <font class="comment"> * do the usual kill_client_connection() checks</font> 01050 <font class="comment"> */</font> 01051 kill_client_connection_unchecked (connection); 01052 } 01053 <font class="keywordflow">else</font> 01054 { 01055 <font class="keywordflow">if</font> (!check_add_match_all (context, connection)) 01056 <font class="keywordflow">return</font> FALSE; 01057 01058 kill_client_connection (context, connection); 01059 } 01060 01061 <font class="keywordflow">return</font> TRUE; 01062 } 01063 01064 <font class="preprocessor">#define NONEXISTENT_SERVICE_NAME "test.this.service.does.not.exist.ewuoiurjdfxcvn"</font> 01065 <font class="preprocessor"></font> 01066 <font class="comment">/* returns TRUE if the correct thing happens,</font> 01067 <font class="comment"> * but the correct thing may include OOM errors.</font> 01068 <font class="comment"> */</font> 01069 <font class="keyword">static</font> dbus_bool_t 01070 check_nonexistent_service_activation (BusContext *context, 01071 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection) 01072 { 01073 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message; 01074 dbus_uint32_t serial; 01075 dbus_bool_t retval; 01076 <a class="code" href="structDBusError.html">DBusError</a> error; 01077 01078 dbus_error_init (&error); 01079 01080 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS, 01081 DBUS_PATH_ORG_FREEDESKTOP_DBUS, 01082 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, 01083 <font class="stringliteral">"ActivateService"</font>); 01084 01085 <font class="keywordflow">if</font> (message == NULL) 01086 <font class="keywordflow">return</font> TRUE; 01087 01088 <font class="keywordflow">if</font> (!dbus_message_append_args (message, 01089 DBUS_TYPE_STRING, NONEXISTENT_SERVICE_NAME, 01090 DBUS_TYPE_UINT32, 0, 01091 DBUS_TYPE_INVALID)) 01092 { 01093 dbus_message_unref (message); 01094 <font class="keywordflow">return</font> TRUE; 01095 } 01096 01097 <font class="keywordflow">if</font> (!dbus_connection_send (connection, message, &serial)) 01098 { 01099 dbus_message_unref (message); 01100 <font class="keywordflow">return</font> TRUE; 01101 } 01102 01103 dbus_message_unref (message); 01104 message = NULL; 01105 01106 bus_test_run_everything (context); 01107 block_connection_until_message_from_bus (context, connection); 01108 bus_test_run_everything (context); 01109 01110 <font class="keywordflow">if</font> (!dbus_connection_get_is_connected (connection)) 01111 { 01112 _dbus_verbose (<font class="stringliteral">"connection was disconnected\n"</font>); 01113 <font class="keywordflow">return</font> TRUE; 01114 } 01115 01116 retval = FALSE; 01117 01118 message = pop_message_waiting_for_memory (connection); 01119 <font class="keywordflow">if</font> (message == NULL) 01120 { 01121 _dbus_warn (<font class="stringliteral">"Did not receive a reply to %s %d on %p\n"</font>, 01122 <font class="stringliteral">"ActivateService"</font>, serial, connection); 01123 <font class="keywordflow">goto</font> out; 01124 } 01125 01126 verbose_message_received (connection, message); 01127 01128 <font class="keywordflow">if</font> (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 01129 { 01130 <font class="keywordflow">if</font> (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS)) 01131 { 01132 _dbus_warn (<font class="stringliteral">"Message has wrong sender %s\n"</font>, 01133 dbus_message_get_sender (message) ? 01134 dbus_message_get_sender (message) : "(none)"); 01135 <font class="keywordflow">goto</font> out; 01136 } 01137 01138 <font class="keywordflow">if</font> (dbus_message_is_error (message, 01139 DBUS_ERROR_NO_MEMORY)) 01140 { 01141 ; <font class="comment">/* good, this is a valid response */</font> 01142 } 01143 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (dbus_message_is_error (message, 01144 DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND)) 01145 { 01146 ; <font class="comment">/* good, this is expected also */</font> 01147 } 01148 <font class="keywordflow">else</font> 01149 { 01150 warn_unexpected (connection, message, <font class="stringliteral">"not this error"</font>); 01151 <font class="keywordflow">goto</font> out; 01152 } 01153 } 01154 <font class="keywordflow">else</font> 01155 { 01156 _dbus_warn (<font class="stringliteral">"Did not expect to successfully activate %s\n"</font>, 01157 NONEXISTENT_SERVICE_NAME); 01158 <font class="keywordflow">goto</font> out; 01159 } 01160 01161 retval = TRUE; 01162 01163 out: 01164 <font class="keywordflow">if</font> (message) 01165 dbus_message_unref (message); 01166 01167 <font class="keywordflow">return</font> retval; 01168 } 01169 01170 <font class="keyword">static</font> dbus_bool_t 01171 check_base_service_activated (BusContext *context, 01172 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 01173 <a class="code" href="structDBusMessage.html">DBusMessage</a> *initial_message, 01174 <font class="keywordtype">char</font> **base_service_p) 01175 { 01176 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message; 01177 dbus_bool_t retval; 01178 <a class="code" href="structDBusError.html">DBusError</a> error; 01179 <font class="keywordtype">char</font> *base_service; 01180 01181 base_service = NULL; 01182 retval = FALSE; 01183 01184 dbus_error_init (&error); 01185 01186 message = initial_message; 01187 dbus_message_ref (message); 01188 01189 <font class="keywordflow">if</font> (dbus_message_is_signal (message, 01190 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, 01191 <font class="stringliteral">"ServiceCreated"</font>)) 01192 { 01193 <font class="keywordtype">char</font> *service_name; 01194 CheckServiceCreatedData scd; 01195 01196 reget_service_name_arg: 01197 <font class="keywordflow">if</font> (!dbus_message_get_args (message, &error, 01198 DBUS_TYPE_STRING, &service_name, 01199 DBUS_TYPE_INVALID)) 01200 { 01201 <font class="keywordflow">if</font> (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 01202 { 01203 dbus_error_free (&error); 01204 _dbus_wait_for_memory (); 01205 <font class="keywordflow">goto</font> reget_service_name_arg; 01206 } 01207 <font class="keywordflow">else</font> 01208 { 01209 _dbus_warn (<font class="stringliteral">"Message %s doesn't have a service name: %s\n"</font>, 01210 <font class="stringliteral">"ServiceCreated"</font>, 01211 error.<a class="code" href="structDBusError.html#m1">message</a>); 01212 dbus_error_free (&error); 01213 <font class="keywordflow">goto</font> out; 01214 } 01215 } 01216 01217 <font class="keywordflow">if</font> (*service_name != <font class="charliteral">':'</font>) 01218 { 01219 _dbus_warn (<font class="stringliteral">"Expected base service activation, got \"%s\" instead\n"</font>, 01220 service_name); 01221 <font class="keywordflow">goto</font> out; 01222 } 01223 01224 base_service = service_name; 01225 service_name = NULL; 01226 01227 scd.skip_connection = connection; 01228 scd.failed = FALSE; 01229 scd.expected_service_name = base_service; 01230 bus_test_clients_foreach (check_service_created_foreach, 01231 &scd); 01232 01233 <font class="keywordflow">if</font> (scd.failed) 01234 <font class="keywordflow">goto</font> out; 01235 } 01236 <font class="keywordflow">else</font> 01237 { 01238 warn_unexpected (connection, message, <font class="stringliteral">"ServiceCreated for base service"</font>); 01239 01240 <font class="keywordflow">goto</font> out; 01241 } 01242 01243 retval = TRUE; 01244 01245 <font class="keywordflow">if</font> (base_service_p) 01246 { 01247 *base_service_p = base_service; 01248 base_service = NULL; 01249 } 01250 01251 out: 01252 <font class="keywordflow">if</font> (message) 01253 dbus_message_unref (message); 01254 01255 <font class="keywordflow">if</font> (base_service) 01256 dbus_free (base_service); 01257 01258 <font class="keywordflow">return</font> retval; 01259 } 01260 01261 <font class="keyword">static</font> dbus_bool_t 01262 check_service_activated (BusContext *context, 01263 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 01264 <font class="keyword">const</font> <font class="keywordtype">char</font> *activated_name, 01265 <font class="keyword">const</font> <font class="keywordtype">char</font> *base_service_name, 01266 <a class="code" href="structDBusMessage.html">DBusMessage</a> *initial_message) 01267 { 01268 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message; 01269 dbus_bool_t retval; 01270 <a class="code" href="structDBusError.html">DBusError</a> error; 01271 dbus_uint32_t activation_result; 01272 01273 retval = FALSE; 01274 01275 dbus_error_init (&error); 01276 01277 message = initial_message; 01278 dbus_message_ref (message); 01279 01280 <font class="keywordflow">if</font> (dbus_message_is_signal (message, 01281 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, 01282 <font class="stringliteral">"ServiceCreated"</font>)) 01283 { 01284 <font class="keywordtype">char</font> *service_name; 01285 CheckServiceCreatedData scd; 01286 01287 reget_service_name_arg: 01288 <font class="keywordflow">if</font> (!dbus_message_get_args (message, &error, 01289 DBUS_TYPE_STRING, &service_name, 01290 DBUS_TYPE_INVALID)) 01291 { 01292 <font class="keywordflow">if</font> (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 01293 { 01294 dbus_error_free (&error); 01295 _dbus_wait_for_memory (); 01296 <font class="keywordflow">goto</font> reget_service_name_arg; 01297 } 01298 <font class="keywordflow">else</font> 01299 { 01300 _dbus_warn (<font class="stringliteral">"Message %s doesn't have a service name: %s\n"</font>, 01301 <font class="stringliteral">"ServiceCreated"</font>, 01302 error.<a class="code" href="structDBusError.html#m1">message</a>); 01303 dbus_error_free (&error); 01304 <font class="keywordflow">goto</font> out; 01305 } 01306 } 01307 01308 <font class="keywordflow">if</font> (strcmp (service_name, activated_name) != 0) 01309 { 01310 _dbus_warn (<font class="stringliteral">"Expected to see service %s created, saw %s instead\n"</font>, 01311 activated_name, service_name); 01312 dbus_free (service_name); 01313 <font class="keywordflow">goto</font> out; 01314 } 01315 01316 scd.skip_connection = connection; 01317 scd.failed = FALSE; 01318 scd.expected_service_name = service_name; 01319 bus_test_clients_foreach (check_service_created_foreach, 01320 &scd); 01321 01322 dbus_free (service_name); 01323 01324 <font class="keywordflow">if</font> (scd.failed) 01325 <font class="keywordflow">goto</font> out; 01326 01327 dbus_message_unref (message); 01328 message = pop_message_waiting_for_memory (connection); 01329 <font class="keywordflow">if</font> (message == NULL) 01330 { 01331 _dbus_warn (<font class="stringliteral">"Expected a reply to %s, got nothing\n"</font>, 01332 <font class="stringliteral">"ActivateService"</font>); 01333 <font class="keywordflow">goto</font> out; 01334 } 01335 } 01336 <font class="keywordflow">else</font> 01337 { 01338 warn_unexpected (connection, message, <font class="stringliteral">"ServiceCreated for the activated name"</font>); 01339 01340 <font class="keywordflow">goto</font> out; 01341 } 01342 01343 <font class="keywordflow">if</font> (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN) 01344 { 01345 warn_unexpected (connection, message, <font class="stringliteral">"reply to ActivateService"</font>); 01346 01347 <font class="keywordflow">goto</font> out; 01348 } 01349 01350 activation_result = 0; 01351 <font class="keywordflow">if</font> (!dbus_message_get_args (message, &error, 01352 DBUS_TYPE_UINT32, &activation_result, 01353 DBUS_TYPE_INVALID)) 01354 { 01355 <font class="keywordflow">if</font> (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 01356 { 01357 _dbus_warn (<font class="stringliteral">"Did not have activation result first argument to %s: %s\n"</font>, 01358 <font class="stringliteral">"ActivateService"</font>, error.<a class="code" href="structDBusError.html#m1">message</a>); 01359 dbus_error_free (&error); 01360 <font class="keywordflow">goto</font> out; 01361 } 01362 01363 dbus_error_free (&error); 01364 } 01365 <font class="keywordflow">else</font> 01366 { 01367 <font class="keywordflow">if</font> (activation_result == DBUS_ACTIVATION_REPLY_ACTIVATED) 01368 ; <font class="comment">/* Good */</font> 01369 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (activation_result == DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE) 01370 ; <font class="comment">/* Good also */</font> 01371 <font class="keywordflow">else</font> 01372 { 01373 _dbus_warn (<font class="stringliteral">"Activation result was 0x%x, no good.\n"</font>, 01374 activation_result); 01375 <font class="keywordflow">goto</font> out; 01376 } 01377 } 01378 01379 dbus_message_unref (message); 01380 message = NULL; 01381 01382 <font class="keywordflow">if</font> (!check_no_leftovers (context)) 01383 { 01384 _dbus_warn (<font class="stringliteral">"Messages were left over after verifying existent activation results\n"</font>); 01385 <font class="keywordflow">goto</font> out; 01386 } 01387 01388 retval = TRUE; 01389 01390 out: 01391 <font class="keywordflow">if</font> (message) 01392 dbus_message_unref (message); 01393 01394 <font class="keywordflow">return</font> retval; 01395 } 01396 01397 <font class="keyword">static</font> dbus_bool_t 01398 check_service_deactivated (BusContext *context, 01399 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 01400 <font class="keyword">const</font> <font class="keywordtype">char</font> *activated_name, 01401 <font class="keyword">const</font> <font class="keywordtype">char</font> *base_service) 01402 { 01403 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message; 01404 dbus_bool_t retval; 01405 <a class="code" href="structDBusError.html">DBusError</a> error; 01406 CheckServiceDeletedData csdd; 01407 01408 message = NULL; 01409 retval = FALSE; 01410 01411 dbus_error_init (&error); 01412 01413 <font class="comment">/* Now we are expecting ServiceDeleted messages for the base</font> 01414 <font class="comment"> * service and the activated_name. The base service</font> 01415 <font class="comment"> * notification is required to come last.</font> 01416 <font class="comment"> */</font> 01417 csdd.expected_service_name = activated_name; 01418 csdd.failed = FALSE; 01419 bus_test_clients_foreach (check_service_deleted_foreach, 01420 &csdd); 01421 01422 <font class="keywordflow">if</font> (csdd.failed) 01423 <font class="keywordflow">goto</font> out; 01424 01425 csdd.expected_service_name = base_service; 01426 csdd.failed = FALSE; 01427 bus_test_clients_foreach (check_service_deleted_foreach, 01428 &csdd); 01429 01430 <font class="keywordflow">if</font> (csdd.failed) 01431 <font class="keywordflow">goto</font> out; 01432 01433 <font class="keywordflow">if</font> (!check_no_leftovers (context)) 01434 { 01435 _dbus_warn (<font class="stringliteral">"Messages were left over after verifying results of service exiting\n"</font>); 01436 <font class="keywordflow">goto</font> out; 01437 } 01438 01439 retval = TRUE; 01440 01441 out: 01442 <font class="keywordflow">if</font> (message) 01443 dbus_message_unref (message); 01444 01445 <font class="keywordflow">return</font> retval; 01446 } 01447 01448 <font class="keyword">static</font> dbus_bool_t 01449 check_send_exit_to_service (BusContext *context, 01450 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 01451 <font class="keyword">const</font> <font class="keywordtype">char</font> *service_name, 01452 <font class="keyword">const</font> <font class="keywordtype">char</font> *base_service) 01453 { 01454 dbus_bool_t got_error; 01455 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message; 01456 dbus_uint32_t serial; 01457 dbus_bool_t retval; 01458 01459 _dbus_verbose (<font class="stringliteral">"Sending exit message to the test service\n"</font>); 01460 01461 retval = FALSE; 01462 01463 <font class="comment">/* Kill off the test service by sending it a quit message */</font> 01464 message = dbus_message_new_method_call (service_name, 01465 <font class="stringliteral">"/org/freedesktop/TestSuite"</font>, 01466 <font class="stringliteral">"org.freedesktop.TestSuite"</font>, 01467 <font class="stringliteral">"Exit"</font>); 01468 01469 <font class="keywordflow">if</font> (message == NULL) 01470 { 01471 <font class="comment">/* Do this again; we still need the service to exit... */</font> 01472 <font class="keywordflow">if</font> (!check_send_exit_to_service (context, connection, 01473 service_name, base_service)) 01474 <font class="keywordflow">goto</font> out; 01475 01476 <font class="keywordflow">return</font> TRUE; 01477 } 01478 01479 <font class="keywordflow">if</font> (!dbus_connection_send (connection, message, &serial)) 01480 { 01481 dbus_message_unref (message); 01482 01483 <font class="comment">/* Do this again; we still need the service to exit... */</font> 01484 <font class="keywordflow">if</font> (!check_send_exit_to_service (context, connection, 01485 service_name, base_service)) 01486 <font class="keywordflow">goto</font> out; 01487 01488 <font class="keywordflow">return</font> TRUE; 01489 } 01490 01491 dbus_message_unref (message); 01492 message = NULL; 01493 01494 <font class="comment">/* send message */</font> 01495 bus_test_run_clients_loop (TRUE); 01496 01497 <font class="comment">/* read it in and write it out to test service */</font> 01498 bus_test_run_bus_loop (context, FALSE); 01499 01500 <font class="comment">/* see if we got an error during message bus dispatching */</font> 01501 bus_test_run_clients_loop (FALSE); 01502 message = dbus_connection_borrow_message (connection); 01503 got_error = message != NULL && dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR; 01504 <font class="keywordflow">if</font> (message) 01505 { 01506 dbus_connection_return_message (connection, message); 01507 message = NULL; 01508 } 01509 01510 <font class="keywordflow">if</font> (!got_error) 01511 { 01512 <font class="comment">/* If no error, wait for the test service to exit */</font> 01513 block_connection_until_message_from_bus (context, connection); 01514 01515 bus_test_run_everything (context); 01516 } 01517 01518 <font class="keywordflow">if</font> (got_error) 01519 { 01520 message = pop_message_waiting_for_memory (connection); 01521 _dbus_assert (message != NULL); 01522 01523 <font class="keywordflow">if</font> (!dbus_message_is_error (message, 01524 DBUS_ERROR_NO_MEMORY)) 01525 { 01526 warn_unexpected (connection, message, 01527 <font class="stringliteral">"a no memory error from asking test service to exit"</font>); 01528 <font class="keywordflow">goto</font> out; 01529 } 01530 01531 _dbus_verbose (<font class="stringliteral">"Got error %s when asking test service to exit\n"</font>, 01532 dbus_message_get_error_name (message)); 01533 01534 <font class="comment">/* Do this again; we still need the service to exit... */</font> 01535 <font class="keywordflow">if</font> (!check_send_exit_to_service (context, connection, 01536 service_name, base_service)) 01537 <font class="keywordflow">goto</font> out; 01538 } 01539 <font class="keywordflow">else</font> 01540 { 01541 <font class="keywordflow">if</font> (!check_service_deactivated (context, connection, 01542 service_name, base_service)) 01543 <font class="keywordflow">goto</font> out; 01544 } 01545 01546 retval = TRUE; 01547 01548 out: 01549 <font class="keywordflow">if</font> (message) 01550 dbus_message_unref (message); 01551 01552 <font class="keywordflow">return</font> retval; 01553 } 01554 01555 <font class="keyword">static</font> dbus_bool_t 01556 check_got_error (BusContext *context, 01557 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 01558 <font class="keyword">const</font> <font class="keywordtype">char</font> *first_error_name, 01559 ...) 01560 { 01561 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message; 01562 dbus_bool_t retval; 01563 va_list ap; 01564 dbus_bool_t error_found; 01565 <font class="keyword">const</font> <font class="keywordtype">char</font> *error_name; 01566 01567 retval = FALSE; 01568 01569 message = pop_message_waiting_for_memory (connection); 01570 <font class="keywordflow">if</font> (message == NULL) 01571 { 01572 _dbus_warn (<font class="stringliteral">"Did not get an expected error\n"</font>); 01573 <font class="keywordflow">goto</font> out; 01574 } 01575 01576 <font class="keywordflow">if</font> (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR) 01577 { 01578 warn_unexpected (connection, message, <font class="stringliteral">"an error"</font>); 01579 01580 <font class="keywordflow">goto</font> out; 01581 } 01582 01583 error_found = FALSE; 01584 01585 va_start (ap, first_error_name); 01586 error_name = first_error_name; 01587 <font class="keywordflow">while</font> (error_name != NULL) 01588 { 01589 <font class="keywordflow">if</font> (dbus_message_is_error (message, error_name)) 01590 { 01591 error_found = TRUE; 01592 <font class="keywordflow">break</font>; 01593 } 01594 error_name = va_arg (ap, <font class="keywordtype">char</font>*); 01595 } 01596 va_end (ap); 01597 01598 <font class="keywordflow">if</font> (!error_found) 01599 { 01600 _dbus_warn (<font class="stringliteral">"Expected error %s or other, got %s instead\n"</font>, 01601 first_error_name, 01602 dbus_message_get_error_name (message)); 01603 <font class="keywordflow">goto</font> out; 01604 } 01605 01606 retval = TRUE; 01607 01608 out: 01609 <font class="keywordflow">if</font> (message) 01610 dbus_message_unref (message); 01611 01612 <font class="keywordflow">return</font> retval; 01613 } 01614 01615 <font class="preprocessor">#define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"</font> 01616 <font class="preprocessor"></font> 01617 <font class="comment">/* returns TRUE if the correct thing happens,</font> 01618 <font class="comment"> * but the correct thing may include OOM errors.</font> 01619 <font class="comment"> */</font> 01620 <font class="keyword">static</font> dbus_bool_t 01621 check_existent_service_activation (BusContext *context, 01622 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection) 01623 { 01624 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message; 01625 dbus_uint32_t serial; 01626 dbus_bool_t retval; 01627 <a class="code" href="structDBusError.html">DBusError</a> error; 01628 <font class="keywordtype">char</font> *base_service; 01629 01630 base_service = NULL; 01631 01632 dbus_error_init (&error); 01633 01634 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS, 01635 DBUS_PATH_ORG_FREEDESKTOP_DBUS, 01636 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, 01637 <font class="stringliteral">"ActivateService"</font>); 01638 01639 <font class="keywordflow">if</font> (message == NULL) 01640 <font class="keywordflow">return</font> TRUE; 01641 01642 <font class="keywordflow">if</font> (!dbus_message_append_args (message, 01643 DBUS_TYPE_STRING, EXISTENT_SERVICE_NAME, 01644 DBUS_TYPE_UINT32, 0, 01645 DBUS_TYPE_INVALID)) 01646 { 01647 dbus_message_unref (message); 01648 <font class="keywordflow">return</font> TRUE; 01649 } 01650 01651 <font class="keywordflow">if</font> (!dbus_connection_send (connection, message, &serial)) 01652 { 01653 dbus_message_unref (message); 01654 <font class="keywordflow">return</font> TRUE; 01655 } 01656 01657 dbus_message_unref (message); 01658 message = NULL; 01659 01660 bus_test_run_everything (context); 01661 01662 <font class="comment">/* now wait for the message bus to hear back from the activated</font> 01663 <font class="comment"> * service.</font> 01664 <font class="comment"> */</font> 01665 block_connection_until_message_from_bus (context, connection); 01666 01667 bus_test_run_everything (context); 01668 01669 <font class="keywordflow">if</font> (!dbus_connection_get_is_connected (connection)) 01670 { 01671 _dbus_verbose (<font class="stringliteral">"connection was disconnected\n"</font>); 01672 <font class="keywordflow">return</font> TRUE; 01673 } 01674 01675 retval = FALSE; 01676 01677 message = pop_message_waiting_for_memory (connection); 01678 <font class="keywordflow">if</font> (message == NULL) 01679 { 01680 _dbus_warn (<font class="stringliteral">"Did not receive any messages after %s %d on %p\n"</font>, 01681 <font class="stringliteral">"ActivateService"</font>, serial, connection); 01682 <font class="keywordflow">goto</font> out; 01683 } 01684 01685 verbose_message_received (connection, message); 01686 _dbus_verbose (<font class="stringliteral">" (after sending %s)\n"</font>, <font class="stringliteral">"ActivateService"</font>); 01687 01688 <font class="keywordflow">if</font> (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 01689 { 01690 <font class="keywordflow">if</font> (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS)) 01691 { 01692 _dbus_warn (<font class="stringliteral">"Message has wrong sender %s\n"</font>, 01693 dbus_message_get_sender (message) ? 01694 dbus_message_get_sender (message) : "(none)"); 01695 <font class="keywordflow">goto</font> out; 01696 } 01697 01698 <font class="keywordflow">if</font> (dbus_message_is_error (message, 01699 DBUS_ERROR_NO_MEMORY)) 01700 { 01701 ; <font class="comment">/* good, this is a valid response */</font> 01702 } 01703 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (dbus_message_is_error (message, 01704 DBUS_ERROR_SPAWN_CHILD_EXITED)) 01705 { 01706 ; <font class="comment">/* good, this is expected also */</font> 01707 } 01708 <font class="keywordflow">else</font> 01709 { 01710 _dbus_warn (<font class="stringliteral">"Did not expect error %s\n"</font>, 01711 dbus_message_get_error_name (message)); 01712 <font class="keywordflow">goto</font> out; 01713 } 01714 } 01715 <font class="keywordflow">else</font> 01716 { 01717 dbus_bool_t got_service_deleted; 01718 dbus_bool_t got_error; 01719 01720 <font class="keywordflow">if</font> (!check_base_service_activated (context, connection, 01721 message, &base_service)) 01722 <font class="keywordflow">goto</font> out; 01723 01724 dbus_message_unref (message); 01725 message = NULL; 01726 01727 <font class="comment">/* We may need to block here for the test service to exit or finish up */</font> 01728 block_connection_until_message_from_bus (context, connection); 01729 01730 message = dbus_connection_borrow_message (connection); 01731 <font class="keywordflow">if</font> (message == NULL) 01732 { 01733 _dbus_warn (<font class="stringliteral">"Did not receive any messages after base service creation notification\n"</font>); 01734 <font class="keywordflow">goto</font> out; 01735 } 01736 01737 got_service_deleted = dbus_message_is_signal (message, 01738 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, 01739 <font class="stringliteral">"ServiceDeleted"</font>); 01740 got_error = dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR; 01741 01742 dbus_connection_return_message (connection, message); 01743 message = NULL; 01744 01745 <font class="keywordflow">if</font> (got_error) 01746 { 01747 <font class="keywordflow">if</font> (!check_got_error (context, connection, 01748 DBUS_ERROR_SPAWN_CHILD_EXITED, 01749 DBUS_ERROR_NO_MEMORY, 01750 NULL)) 01751 <font class="keywordflow">goto</font> out; 01752 01753 <font class="comment">/* A service deleted should be coming along now after this error.</font> 01754 <font class="comment"> * We can also get the error *after* the service deleted.</font> 01755 <font class="comment"> */</font> 01756 got_service_deleted = TRUE; 01757 } 01758 01759 <font class="keywordflow">if</font> (got_service_deleted) 01760 { 01761 <font class="comment">/* The service started up and got a base address, but then</font> 01762 <font class="comment"> * failed to register under EXISTENT_SERVICE_NAME</font> 01763 <font class="comment"> */</font> 01764 CheckServiceDeletedData csdd; 01765 01766 csdd.expected_service_name = base_service; 01767 csdd.failed = FALSE; 01768 bus_test_clients_foreach (check_service_deleted_foreach, 01769 &csdd); 01770 01771 <font class="keywordflow">if</font> (csdd.failed) 01772 <font class="keywordflow">goto</font> out; 01773 01774 <font class="comment">/* Now we should get an error about the service exiting</font> 01775 <font class="comment"> * if we didn't get it before.</font> 01776 <font class="comment"> */</font> 01777 <font class="keywordflow">if</font> (!got_error) 01778 { 01779 block_connection_until_message_from_bus (context, connection); 01780 01781 <font class="comment">/* and process everything again */</font> 01782 bus_test_run_everything (context); 01783 01784 <font class="keywordflow">if</font> (!check_got_error (context, connection, 01785 DBUS_ERROR_SPAWN_CHILD_EXITED, 01786 NULL)) 01787 <font class="keywordflow">goto</font> out; 01788 } 01789 } 01790 <font class="keywordflow">else</font> 01791 { 01792 message = pop_message_waiting_for_memory (connection); 01793 <font class="keywordflow">if</font> (message == NULL) 01794 { 01795 _dbus_warn (<font class="stringliteral">"Failed to pop message we just put back! should have been a ServiceCreated\n"</font>); 01796 <font class="keywordflow">goto</font> out; 01797 } 01798 01799 <font class="keywordflow">if</font> (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME, 01800 base_service, message)) 01801 <font class="keywordflow">goto</font> out; 01802 01803 dbus_message_unref (message); 01804 message = NULL; 01805 01806 01807 <font class="keywordflow">if</font> (!check_no_leftovers (context)) 01808 { 01809 _dbus_warn (<font class="stringliteral">"Messages were left over after successful activation\n"</font>); 01810 <font class="keywordflow">goto</font> out; 01811 } 01812 01813 <font class="keywordflow">if</font> (!check_send_exit_to_service (context, connection, 01814 EXISTENT_SERVICE_NAME, base_service)) 01815 <font class="keywordflow">goto</font> out; 01816 } 01817 } 01818 01819 retval = TRUE; 01820 01821 out: 01822 <font class="keywordflow">if</font> (message) 01823 dbus_message_unref (message); 01824 01825 <font class="keywordflow">if</font> (base_service) 01826 dbus_free (base_service); 01827 01828 <font class="keywordflow">return</font> retval; 01829 } 01830 01831 <font class="comment">/* returns TRUE if the correct thing happens,</font> 01832 <font class="comment"> * but the correct thing may include OOM errors.</font> 01833 <font class="comment"> */</font> 01834 <font class="keyword">static</font> dbus_bool_t 01835 check_segfault_service_activation (BusContext *context, 01836 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection) 01837 { 01838 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message; 01839 dbus_uint32_t serial; 01840 dbus_bool_t retval; 01841 <a class="code" href="structDBusError.html">DBusError</a> error; 01842 01843 dbus_error_init (&error); 01844 01845 message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS, 01846 DBUS_PATH_ORG_FREEDESKTOP_DBUS, 01847 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, 01848 <font class="stringliteral">"ActivateService"</font>); 01849 01850 <font class="keywordflow">if</font> (message == NULL) 01851 <font class="keywordflow">return</font> TRUE; 01852 01853 <font class="keywordflow">if</font> (!dbus_message_append_args (message, 01854 DBUS_TYPE_STRING, 01855 <font class="stringliteral">"org.freedesktop.DBus.TestSuiteSegfaultService"</font>, 01856 DBUS_TYPE_UINT32, 0, 01857 DBUS_TYPE_INVALID)) 01858 { 01859 dbus_message_unref (message); 01860 <font class="keywordflow">return</font> TRUE; 01861 } 01862 01863 <font class="keywordflow">if</font> (!dbus_connection_send (connection, message, &serial)) 01864 { 01865 dbus_message_unref (message); 01866 <font class="keywordflow">return</font> TRUE; 01867 } 01868 01869 dbus_message_unref (message); 01870 message = NULL; 01871 01872 bus_test_run_everything (context); 01873 block_connection_until_message_from_bus (context, connection); 01874 bus_test_run_everything (context); 01875 01876 <font class="keywordflow">if</font> (!dbus_connection_get_is_connected (connection)) 01877 { 01878 _dbus_verbose (<font class="stringliteral">"connection was disconnected\n"</font>); 01879 <font class="keywordflow">return</font> TRUE; 01880 } 01881 01882 retval = FALSE; 01883 01884 message = pop_message_waiting_for_memory (connection); 01885 <font class="keywordflow">if</font> (message == NULL) 01886 { 01887 _dbus_warn (<font class="stringliteral">"Did not receive a reply to %s %d on %p\n"</font>, 01888 <font class="stringliteral">"ActivateService"</font>, serial, connection); 01889 <font class="keywordflow">goto</font> out; 01890 } 01891 01892 verbose_message_received (connection, message); 01893 01894 <font class="keywordflow">if</font> (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 01895 { 01896 <font class="keywordflow">if</font> (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS)) 01897 { 01898 _dbus_warn (<font class="stringliteral">"Message has wrong sender %s\n"</font>, 01899 dbus_message_get_sender (message) ? 01900 dbus_message_get_sender (message) : "(none)"); 01901 <font class="keywordflow">goto</font> out; 01902 } 01903 01904 <font class="keywordflow">if</font> (dbus_message_is_error (message, 01905 DBUS_ERROR_NO_MEMORY)) 01906 { 01907 ; <font class="comment">/* good, this is a valid response */</font> 01908 } 01909 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (dbus_message_is_error (message, 01910 DBUS_ERROR_SPAWN_CHILD_SIGNALED)) 01911 { 01912 ; <font class="comment">/* good, this is expected also */</font> 01913 } 01914 <font class="keywordflow">else</font> 01915 { 01916 warn_unexpected (connection, message, <font class="stringliteral">"not this error"</font>); 01917 01918 <font class="keywordflow">goto</font> out; 01919 } 01920 } 01921 <font class="keywordflow">else</font> 01922 { 01923 _dbus_warn (<font class="stringliteral">"Did not expect to successfully activate segfault service\n"</font>); 01924 <font class="keywordflow">goto</font> out; 01925 } 01926 01927 retval = TRUE; 01928 01929 out: 01930 <font class="keywordflow">if</font> (message) 01931 dbus_message_unref (message); 01932 01933 <font class="keywordflow">return</font> retval; 01934 } 01935 01936 <font class="keyword">typedef</font> <font class="keyword">struct</font> 01937 <font class="keyword"></font>{ 01938 Check1Func func; 01939 BusContext *context; 01940 } Check1Data; 01941 01942 <font class="keyword">static</font> dbus_bool_t 01943 check_oom_check1_func (<font class="keywordtype">void</font> *data) 01944 { 01945 Check1Data *d = data; 01946 01947 <font class="keywordflow">if</font> (! (* d->func) (d->context)) 01948 <font class="keywordflow">return</font> FALSE; 01949 01950 <font class="keywordflow">if</font> (!check_no_leftovers (d->context)) 01951 { 01952 _dbus_warn (<font class="stringliteral">"Messages were left over, should be covered by test suite\n"</font>); 01953 <font class="keywordflow">return</font> FALSE; 01954 } 01955 01956 <font class="keywordflow">return</font> TRUE; 01957 } 01958 01959 <font class="keyword">static</font> <font class="keywordtype">void</font> 01960 check1_try_iterations (BusContext *context, 01961 <font class="keyword">const</font> <font class="keywordtype">char</font> *description, 01962 Check1Func func) 01963 { 01964 Check1Data d; 01965 01966 d.func = func; 01967 d.context = context; 01968 01969 <font class="keywordflow">if</font> (!_dbus_test_oom_handling (description, check_oom_check1_func, 01970 &d)) 01971 _dbus_assert_not_reached (<font class="stringliteral">"test failed"</font>); 01972 } 01973 01974 <font class="keyword">typedef</font> <font class="keyword">struct</font> 01975 <font class="keyword"></font>{ 01976 Check2Func func; 01977 BusContext *context; 01978 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection; 01979 } Check2Data; 01980 01981 <font class="keyword">static</font> dbus_bool_t 01982 check_oom_check2_func (<font class="keywordtype">void</font> *data) 01983 { 01984 Check2Data *d = data; 01985 01986 <font class="keywordflow">if</font> (! (* d->func) (d->context, d->connection)) 01987 <font class="keywordflow">return</font> FALSE; 01988 01989 <font class="keywordflow">if</font> (!check_no_leftovers (d->context)) 01990 { 01991 _dbus_warn (<font class="stringliteral">"Messages were left over, should be covered by test suite"</font>); 01992 <font class="keywordflow">return</font> FALSE; 01993 } 01994 01995 <font class="keywordflow">return</font> TRUE; 01996 } 01997 01998 <font class="keyword">static</font> <font class="keywordtype">void</font> 01999 check2_try_iterations (BusContext *context, 02000 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 02001 <font class="keyword">const</font> <font class="keywordtype">char</font> *description, 02002 Check2Func func) 02003 { 02004 Check2Data d; 02005 02006 d.func = func; 02007 d.context = context; 02008 d.connection = connection; 02009 02010 <font class="keywordflow">if</font> (!_dbus_test_oom_handling (description, check_oom_check2_func, 02011 &d)) 02012 _dbus_assert_not_reached (<font class="stringliteral">"test failed"</font>); 02013 } 02014 02015 dbus_bool_t 02016 bus_dispatch_test (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *test_data_dir) 02017 { 02018 BusContext *context; 02019 <a class="code" href="structDBusConnection.html">DBusConnection</a> *foo; 02020 <a class="code" href="structDBusConnection.html">DBusConnection</a> *bar; 02021 <a class="code" href="structDBusConnection.html">DBusConnection</a> *baz; 02022 <a class="code" href="structDBusError.html">DBusError</a> error; 02023 02024 dbus_error_init (&error); 02025 02026 context = bus_context_new_test (test_data_dir, 02027 <font class="stringliteral">"valid-config-files/debug-allow-all.conf"</font>); 02028 <font class="keywordflow">if</font> (context == NULL) 02029 <font class="keywordflow">return</font> FALSE; 02030 02031 foo = dbus_connection_open (<font class="stringliteral">"debug-pipe:name=test-server"</font>, &error); 02032 <font class="keywordflow">if</font> (foo == NULL) 02033 _dbus_assert_not_reached (<font class="stringliteral">"could not alloc connection"</font>); 02034 02035 <font class="keywordflow">if</font> (!bus_setup_debug_client (foo)) 02036 _dbus_assert_not_reached (<font class="stringliteral">"could not set up connection"</font>); 02037 02038 <font class="keywordflow">if</font> (!check_hello_message (context, foo)) 02039 _dbus_assert_not_reached (<font class="stringliteral">"hello message failed"</font>); 02040 02041 <font class="keywordflow">if</font> (!check_add_match_all (context, foo)) 02042 _dbus_assert_not_reached (<font class="stringliteral">"AddMatch message failed"</font>); 02043 02044 bar = dbus_connection_open (<font class="stringliteral">"debug-pipe:name=test-server"</font>, &error); 02045 <font class="keywordflow">if</font> (bar == NULL) 02046 _dbus_assert_not_reached (<font class="stringliteral">"could not alloc connection"</font>); 02047 02048 <font class="keywordflow">if</font> (!bus_setup_debug_client (bar)) 02049 _dbus_assert_not_reached (<font class="stringliteral">"could not set up connection"</font>); 02050 02051 <font class="keywordflow">if</font> (!check_hello_message (context, bar)) 02052 _dbus_assert_not_reached (<font class="stringliteral">"hello message failed"</font>); 02053 02054 <font class="keywordflow">if</font> (!check_add_match_all (context, bar)) 02055 _dbus_assert_not_reached (<font class="stringliteral">"AddMatch message failed"</font>); 02056 02057 baz = dbus_connection_open (<font class="stringliteral">"debug-pipe:name=test-server"</font>, &error); 02058 <font class="keywordflow">if</font> (baz == NULL) 02059 _dbus_assert_not_reached (<font class="stringliteral">"could not alloc connection"</font>); 02060 02061 <font class="keywordflow">if</font> (!bus_setup_debug_client (baz)) 02062 _dbus_assert_not_reached (<font class="stringliteral">"could not set up connection"</font>); 02063 02064 <font class="keywordflow">if</font> (!check_hello_message (context, baz)) 02065 _dbus_assert_not_reached (<font class="stringliteral">"hello message failed"</font>); 02066 02067 <font class="keywordflow">if</font> (!check_add_match_all (context, baz)) 02068 _dbus_assert_not_reached (<font class="stringliteral">"AddMatch message failed"</font>); 02069 02070 <font class="keywordflow">if</font> (!check_no_leftovers (context)) 02071 { 02072 _dbus_warn (<font class="stringliteral">"Messages were left over after setting up initial connections"</font>); 02073 _dbus_assert_not_reached (<font class="stringliteral">"initial connection setup failed"</font>); 02074 } 02075 02076 check1_try_iterations (context, <font class="stringliteral">"create_and_hello"</font>, 02077 check_hello_connection); 02078 02079 check2_try_iterations (context, foo, <font class="stringliteral">"nonexistent_service_activation"</font>, 02080 check_nonexistent_service_activation); 02081 02082 check2_try_iterations (context, foo, <font class="stringliteral">"segfault_service_activation"</font>, 02083 check_segfault_service_activation); 02084 02085 check2_try_iterations (context, foo, <font class="stringliteral">"existent_service_activation"</font>, 02086 check_existent_service_activation); 02087 02088 _dbus_verbose (<font class="stringliteral">"Disconnecting foo, bar, and baz\n"</font>); 02089 02090 kill_client_connection_unchecked (foo); 02091 kill_client_connection_unchecked (bar); 02092 kill_client_connection_unchecked (baz); 02093 02094 bus_context_unref (context); 02095 02096 <font class="keywordflow">return</font> TRUE; 02097 } 02098 02099 dbus_bool_t 02100 bus_dispatch_sha1_test (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *test_data_dir) 02101 { 02102 BusContext *context; 02103 <a class="code" href="structDBusConnection.html">DBusConnection</a> *foo; 02104 <a class="code" href="structDBusError.html">DBusError</a> error; 02105 02106 dbus_error_init (&error); 02107 02108 <font class="comment">/* Test SHA1 authentication */</font> 02109 _dbus_verbose (<font class="stringliteral">"Testing SHA1 context\n"</font>); 02110 02111 context = bus_context_new_test (test_data_dir, 02112 <font class="stringliteral">"valid-config-files/debug-allow-all-sha1.conf"</font>); 02113 <font class="keywordflow">if</font> (context == NULL) 02114 <font class="keywordflow">return</font> FALSE; 02115 02116 foo = dbus_connection_open (<font class="stringliteral">"debug-pipe:name=test-server"</font>, &error); 02117 <font class="keywordflow">if</font> (foo == NULL) 02118 _dbus_assert_not_reached (<font class="stringliteral">"could not alloc connection"</font>); 02119 02120 <font class="keywordflow">if</font> (!bus_setup_debug_client (foo)) 02121 _dbus_assert_not_reached (<font class="stringliteral">"could not set up connection"</font>); 02122 02123 <font class="keywordflow">if</font> (!check_hello_message (context, foo)) 02124 _dbus_assert_not_reached (<font class="stringliteral">"hello message failed"</font>); 02125 02126 <font class="keywordflow">if</font> (!check_add_match_all (context, foo)) 02127 _dbus_assert_not_reached (<font class="stringliteral">"addmatch message failed"</font>); 02128 02129 <font class="keywordflow">if</font> (!check_no_leftovers (context)) 02130 { 02131 _dbus_warn (<font class="stringliteral">"Messages were left over after setting up initial SHA-1 connection\n"</font>); 02132 _dbus_assert_not_reached (<font class="stringliteral">"initial connection setup failed"</font>); 02133 } 02134 02135 check1_try_iterations (context, <font class="stringliteral">"create_and_hello_sha1"</font>, 02136 check_hello_connection); 02137 02138 kill_client_connection_unchecked (foo); 02139 02140 bus_context_unref (context); 02141 02142 <font class="keywordflow">return</font> TRUE; 02143 } 02144 02145 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_BUILD_TESTS */</font> </pre></div><hr><address align="right"><small>Generated on Mon Sep 29 21:31:02 2003 for D-BUS by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border=0 width=110 height=53></a>1.2.15 </small></address> </body> </html>