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