test-service.c revision be51ff7e5ef2e9370fd2417614781f688576d37a
1 2#include "test-utils.h" 3#ifdef HAVE_UNISTD_H 4#include <unistd.h> 5#endif 6 7static DBusLoop *loop; 8static dbus_bool_t already_quit = FALSE; 9static dbus_bool_t hello_from_self_reply_received = FALSE; 10 11static void 12quit (void) 13{ 14 if (!already_quit) 15 { 16 _dbus_loop_quit (loop); 17 already_quit = TRUE; 18 } 19} 20 21static void 22die (const char *message) 23{ 24 fprintf (stderr, "*** test-service: %s", message); 25 exit (1); 26} 27 28static void 29check_hello_from_self_reply (DBusPendingCall *pcall, 30 void *user_data) 31{ 32 DBusMessage *reply; 33 DBusMessage *echo_message, *echo_reply = NULL; 34 DBusError error; 35 DBusConnection *connection; 36 37 int type; 38 39 dbus_error_init (&error); 40 41 connection = dbus_bus_get (DBUS_BUS_STARTER, &error); 42 if (connection == NULL) 43 { 44 fprintf (stderr, "*** Failed to open connection to activating message bus: %s\n", 45 error.message); 46 dbus_error_free (&error); 47 die("no memory"); 48 } 49 50 51 echo_message = (DBusMessage *)user_data; 52 53 reply = dbus_pending_call_steal_reply (pcall); 54 55 type = dbus_message_get_type (reply); 56 57 if (type == DBUS_MESSAGE_TYPE_METHOD_RETURN) 58 { 59 const char *s; 60 printf ("Reply from HelloFromSelf received\n"); 61 62 if (!dbus_message_get_args (echo_message, 63 &error, 64 DBUS_TYPE_STRING, &s, 65 DBUS_TYPE_INVALID)) 66 { 67 echo_reply = dbus_message_new_error (echo_message, 68 error.name, 69 error.message); 70 71 if (echo_reply == NULL) 72 die ("No memory\n"); 73 74 } 75 else 76 { 77 echo_reply = dbus_message_new_method_return (echo_message); 78 if (echo_reply == NULL) 79 die ("No memory\n"); 80 81 if (!dbus_message_append_args (echo_reply, 82 DBUS_TYPE_STRING, &s, 83 DBUS_TYPE_INVALID)) 84 die ("No memory"); 85 } 86 87 if (!dbus_connection_send (connection, echo_reply, NULL)) 88 die ("No memory\n"); 89 90 dbus_message_unref (echo_reply); 91 } 92 else if (type == DBUS_MESSAGE_TYPE_ERROR) 93 { 94 dbus_set_error_from_message (&error, reply); 95 printf ("Error type in reply: %s\n", error.message); 96 97 if (strcmp (error.name, DBUS_ERROR_NO_MEMORY) != 0) 98 { 99 echo_reply = dbus_message_new_error (echo_reply, 100 error.name, 101 error.message); 102 103 if (echo_reply == NULL) 104 die ("No memory\n"); 105 106 if (!dbus_connection_send (connection, echo_reply, NULL)) 107 die ("No memory\n"); 108 109 dbus_message_unref (echo_reply); 110 } 111 dbus_error_free (&error); 112 } 113 else 114 _dbus_assert_not_reached ("Unexpected message received\n"); 115 116 hello_from_self_reply_received = TRUE; 117 118 dbus_message_unref (reply); 119 dbus_message_unref (echo_message); 120 dbus_pending_call_unref (pcall); 121 dbus_connection_unref (connection); 122} 123 124static DBusHandlerResult 125handle_run_hello_from_self (DBusConnection *connection, 126 DBusMessage *message) 127{ 128 DBusError error; 129 DBusMessage *reply, *self_message; 130 DBusPendingCall *pcall; 131 char *s; 132 133 _dbus_verbose ("sending reply to Echo method\n"); 134 135 dbus_error_init (&error); 136 137 if (!dbus_message_get_args (message, 138 &error, 139 DBUS_TYPE_STRING, &s, 140 DBUS_TYPE_INVALID)) 141 { 142 reply = dbus_message_new_error (message, 143 error.name, 144 error.message); 145 146 if (reply == NULL) 147 die ("No memory\n"); 148 149 if (!dbus_connection_send (connection, reply, NULL)) 150 die ("No memory\n"); 151 152 dbus_message_unref (reply); 153 154 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 155 } 156 printf ("Sending HelloFromSelf\n"); 157 158 _dbus_verbose ("*** Sending message to self\n"); 159 self_message = dbus_message_new_method_call ("org.freedesktop.DBus.TestSuiteEchoService", 160 "/org/freedesktop/TestSuite", 161 "org.freedesktop.TestSuite", 162 "HelloFromSelf"); 163 164 if (self_message == NULL) 165 die ("No memory"); 166 167 if (!dbus_connection_send_with_reply (connection, self_message, &pcall, -1)) 168 die("No memory"); 169 170 dbus_message_ref (message); 171 if (!dbus_pending_call_set_notify (pcall, check_hello_from_self_reply, (void *)message, NULL)) 172 die("No memory"); 173 174 printf ("Sent HelloFromSelf\n"); 175 return DBUS_HANDLER_RESULT_HANDLED; 176} 177 178static DBusHandlerResult 179handle_echo (DBusConnection *connection, 180 DBusMessage *message) 181{ 182 DBusError error; 183 DBusMessage *reply; 184 char *s; 185 186 _dbus_verbose ("sending reply to Echo method\n"); 187 188 dbus_error_init (&error); 189 190 if (!dbus_message_get_args (message, 191 &error, 192 DBUS_TYPE_STRING, &s, 193 DBUS_TYPE_INVALID)) 194 { 195 reply = dbus_message_new_error (message, 196 error.name, 197 error.message); 198 199 if (reply == NULL) 200 die ("No memory\n"); 201 202 if (!dbus_connection_send (connection, reply, NULL)) 203 die ("No memory\n"); 204 205 dbus_message_unref (reply); 206 207 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 208 } 209 210 reply = dbus_message_new_method_return (message); 211 if (reply == NULL) 212 die ("No memory\n"); 213 214 if (!dbus_message_append_args (reply, 215 DBUS_TYPE_STRING, &s, 216 DBUS_TYPE_INVALID)) 217 die ("No memory"); 218 219 if (!dbus_connection_send (connection, reply, NULL)) 220 die ("No memory\n"); 221 222 fprintf (stderr, "Echo service echoed string: \"%s\"\n", s); 223 224 dbus_message_unref (reply); 225 226 return DBUS_HANDLER_RESULT_HANDLED; 227} 228 229static DBusHandlerResult 230handle_delay_echo (DBusConnection *connection, 231 DBusMessage *message) 232{ 233 DBusError error; 234 DBusMessage *reply; 235 char *s; 236 237 _dbus_verbose ("sleeping for a short time\n"); 238 239 _dbus_sleep_milliseconds (50); 240 241 _dbus_verbose ("sending reply to DelayEcho method\n"); 242 243 dbus_error_init (&error); 244 245 if (!dbus_message_get_args (message, 246 &error, 247 DBUS_TYPE_STRING, &s, 248 DBUS_TYPE_INVALID)) 249 { 250 reply = dbus_message_new_error (message, 251 error.name, 252 error.message); 253 254 if (reply == NULL) 255 die ("No memory\n"); 256 257 if (!dbus_connection_send (connection, reply, NULL)) 258 die ("No memory\n"); 259 260 dbus_message_unref (reply); 261 262 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 263 } 264 265 reply = dbus_message_new_method_return (message); 266 if (reply == NULL) 267 die ("No memory\n"); 268 269 if (!dbus_message_append_args (reply, 270 DBUS_TYPE_STRING, &s, 271 DBUS_TYPE_INVALID)) 272 die ("No memory"); 273 274 if (!dbus_connection_send (connection, reply, NULL)) 275 die ("No memory\n"); 276 277 fprintf (stderr, "DelayEcho service echoed string: \"%s\"\n", s); 278 279 dbus_message_unref (reply); 280 281 return DBUS_HANDLER_RESULT_HANDLED; 282} 283 284 285static void 286path_unregistered_func (DBusConnection *connection, 287 void *user_data) 288{ 289 /* connection was finalized */ 290} 291 292static DBusHandlerResult 293path_message_func (DBusConnection *connection, 294 DBusMessage *message, 295 void *user_data) 296{ 297 if (dbus_message_is_method_call (message, 298 "org.freedesktop.TestSuite", 299 "Echo")) 300 return handle_echo (connection, message); 301 else if (dbus_message_is_method_call (message, 302 "org.freedesktop.TestSuite", 303 "DelayEcho")) 304 return handle_delay_echo (connection, message); 305 else if (dbus_message_is_method_call (message, 306 "org.freedesktop.TestSuite", 307 "Exit")) 308 { 309 quit (); 310 return DBUS_HANDLER_RESULT_HANDLED; 311 } 312 else if (dbus_message_is_method_call (message, 313 "org.freedesktop.TestSuite", 314 "EmitFoo")) 315 { 316 /* Emit the Foo signal */ 317 DBusMessage *signal; 318 double v_DOUBLE; 319 320 _dbus_verbose ("emitting signal Foo\n"); 321 322 signal = dbus_message_new_signal ("/org/freedesktop/TestSuite", 323 "org.freedesktop.TestSuite", 324 "Foo"); 325 if (signal == NULL) 326 die ("No memory\n"); 327 328 v_DOUBLE = 42.6; 329 if (!dbus_message_append_args (signal, 330 DBUS_TYPE_DOUBLE, &v_DOUBLE, 331 DBUS_TYPE_INVALID)) 332 die ("No memory"); 333 334 if (!dbus_connection_send (connection, signal, NULL)) 335 die ("No memory\n"); 336 337 return DBUS_HANDLER_RESULT_HANDLED; 338 } 339 340 else if (dbus_message_is_method_call (message, 341 "org.freedesktop.TestSuite", 342 "RunHelloFromSelf")) 343 { 344 return handle_run_hello_from_self (connection, message); 345 } 346 else if (dbus_message_is_method_call (message, 347 "org.freedesktop.TestSuite", 348 "HelloFromSelf")) 349 { 350 DBusMessage *reply; 351 printf ("Received the HelloFromSelf message\n"); 352 353 reply = dbus_message_new_method_return (message); 354 if (reply == NULL) 355 die ("No memory"); 356 357 if (!dbus_connection_send (connection, reply, NULL)) 358 die ("No memory"); 359 360 return DBUS_HANDLER_RESULT_HANDLED; 361 } 362 else 363 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 364} 365 366static DBusObjectPathVTable 367echo_vtable = { 368 path_unregistered_func, 369 path_message_func, 370 NULL, 371}; 372 373 374static const char* echo_path = "/org/freedesktop/TestSuite" ; 375 376static DBusHandlerResult 377filter_func (DBusConnection *connection, 378 DBusMessage *message, 379 void *user_data) 380{ 381 if (dbus_message_is_signal (message, 382 DBUS_INTERFACE_LOCAL, 383 "Disconnected")) 384 { 385 quit (); 386 return DBUS_HANDLER_RESULT_HANDLED; 387 } 388 else 389 { 390 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 391 } 392} 393 394int 395main (int argc, 396 char **argv) 397{ 398 DBusError error; 399 int result; 400 DBusConnection *connection; 401 const char *name; 402 dbus_bool_t do_fork; 403 404 if (argc != 3) 405 { 406 name = "org.freedesktop.DBus.TestSuiteEchoService"; 407 do_fork = FALSE; 408 } 409 else 410 { 411 name = argv[1]; 412#ifndef DBUS_WIN 413 do_fork = strcmp (argv[2], "fork") == 0; 414#endif 415 } 416 417 /* The bare minimum for simulating a program "daemonizing"; the intent 418 * is to test services which move from being legacy init scripts to 419 * activated services. 420 * https://bugzilla.redhat.com/show_bug.cgi?id=545267 421 */ 422#ifndef DBUS_WIN 423 if (do_fork) 424 { 425 pid_t pid = fork (); 426 if (pid != 0) 427 exit (0); 428 sleep (1); 429 } 430#endif 431 dbus_error_init (&error); 432 connection = dbus_bus_get (DBUS_BUS_STARTER, &error); 433 if (connection == NULL) 434 { 435 fprintf (stderr, "*** Failed to open connection to activating message bus: %s\n", 436 error.message); 437 dbus_error_free (&error); 438 return 1; 439 } 440 441 loop = _dbus_loop_new (); 442 if (loop == NULL) 443 die ("No memory\n"); 444 445 if (!test_connection_setup (loop, connection)) 446 die ("No memory\n"); 447 448 if (!dbus_connection_add_filter (connection, 449 filter_func, NULL, NULL)) 450 die ("No memory"); 451 452 if (!dbus_connection_register_object_path (connection, 453 echo_path, 454 &echo_vtable, 455 (void*) 0xdeadbeef)) 456 die ("No memory"); 457 458 { 459 void *d; 460 if (!dbus_connection_get_object_path_data (connection, echo_path, &d)) 461 die ("No memory"); 462 if (d != (void*) 0xdeadbeef) 463 die ("dbus_connection_get_object_path_data() doesn't seem to work right\n"); 464 } 465 466 result = dbus_bus_request_name (connection, name, 467 0, &error); 468 if (dbus_error_is_set (&error)) 469 { 470 fprintf (stderr, "Error %s\n", error.message); 471 _dbus_verbose ("*** Failed to acquire service: %s\n", 472 error.message); 473 dbus_error_free (&error); 474 exit (1); 475 } 476 477 _dbus_verbose ("*** Test service entering main loop\n"); 478 _dbus_loop_run (loop); 479 480 test_connection_shutdown (loop, connection); 481 482 dbus_connection_remove_filter (connection, filter_func, NULL); 483 484 dbus_connection_unref (connection); 485 486 _dbus_loop_unref (loop); 487 loop = NULL; 488 489 dbus_shutdown (); 490 491 _dbus_verbose ("*** Test service exiting\n"); 492 493 return 0; 494} 495