LCOV - code coverage report
Current view: top level - glib/gio/tests - gdbus-example-server.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 0 99 0.0 %
Date: 2024-04-23 05:16:05 Functions: 0 8 0.0 %
Branches: 0 44 0.0 %

           Branch data     Line data    Source code
       1                 :            : #include <gio/gio.h>
       2                 :            : #include <stdlib.h>
       3                 :            : 
       4                 :            : #ifdef G_OS_UNIX
       5                 :            : #include <gio/gunixfdlist.h>
       6                 :            : /* For STDOUT_FILENO */
       7                 :            : #include <unistd.h>
       8                 :            : #endif
       9                 :            : 
      10                 :            : /* ---------------------------------------------------------------------------------------------------- */
      11                 :            : 
      12                 :            : static GDBusNodeInfo *introspection_data = NULL;
      13                 :            : 
      14                 :            : /* Introspection data for the service we are exporting */
      15                 :            : static const gchar introspection_xml[] =
      16                 :            :   "<node>"
      17                 :            :   "  <interface name='org.gtk.GDBus.TestInterface'>"
      18                 :            :   "    <annotation name='org.gtk.GDBus.Annotation' value='OnInterface'/>"
      19                 :            :   "    <annotation name='org.gtk.GDBus.Annotation' value='AlsoOnInterface'/>"
      20                 :            :   "    <method name='HelloWorld'>"
      21                 :            :   "      <annotation name='org.gtk.GDBus.Annotation' value='OnMethod'/>"
      22                 :            :   "      <arg type='s' name='greeting' direction='in'/>"
      23                 :            :   "      <arg type='s' name='response' direction='out'/>"
      24                 :            :   "    </method>"
      25                 :            :   "    <method name='EmitSignal'>"
      26                 :            :   "      <arg type='d' name='speed_in_mph' direction='in'>"
      27                 :            :   "        <annotation name='org.gtk.GDBus.Annotation' value='OnArg'/>"
      28                 :            :   "      </arg>"
      29                 :            :   "    </method>"
      30                 :            :   "    <method name='GimmeStdout'/>"
      31                 :            :   "    <signal name='VelocityChanged'>"
      32                 :            :   "      <annotation name='org.gtk.GDBus.Annotation' value='Onsignal'/>"
      33                 :            :   "      <arg type='d' name='speed_in_mph'/>"
      34                 :            :   "      <arg type='s' name='speed_as_string'>"
      35                 :            :   "        <annotation name='org.gtk.GDBus.Annotation' value='OnArg_NonFirst'/>"
      36                 :            :   "      </arg>"
      37                 :            :   "    </signal>"
      38                 :            :   "    <property type='s' name='FluxCapicitorName' access='read'>"
      39                 :            :   "      <annotation name='org.gtk.GDBus.Annotation' value='OnProperty'>"
      40                 :            :   "        <annotation name='org.gtk.GDBus.Annotation' value='OnAnnotation_YesThisIsCrazy'/>"
      41                 :            :   "      </annotation>"
      42                 :            :   "    </property>"
      43                 :            :   "    <property type='s' name='Title' access='readwrite'/>"
      44                 :            :   "    <property type='s' name='ReadingAlwaysThrowsError' access='read'/>"
      45                 :            :   "    <property type='s' name='WritingAlwaysThrowsError' access='readwrite'/>"
      46                 :            :   "    <property type='s' name='OnlyWritable' access='write'/>"
      47                 :            :   "    <property type='s' name='Foo' access='read'/>"
      48                 :            :   "    <property type='s' name='Bar' access='read'/>"
      49                 :            :   "  </interface>"
      50                 :            :   "</node>";
      51                 :            : 
      52                 :            : /* ---------------------------------------------------------------------------------------------------- */
      53                 :            : 
      54                 :            : static void
      55                 :          0 : handle_method_call (GDBusConnection       *connection,
      56                 :            :                     const gchar           *sender,
      57                 :            :                     const gchar           *object_path,
      58                 :            :                     const gchar           *interface_name,
      59                 :            :                     const gchar           *method_name,
      60                 :            :                     GVariant              *parameters,
      61                 :            :                     GDBusMethodInvocation *invocation,
      62                 :            :                     gpointer               user_data)
      63                 :            : {
      64         [ #  # ]:          0 :   if (g_strcmp0 (method_name, "HelloWorld") == 0)
      65                 :            :     {
      66                 :            :       const gchar *greeting;
      67                 :            : 
      68                 :          0 :       g_variant_get (parameters, "(&s)", &greeting);
      69                 :            : 
      70         [ #  # ]:          0 :       if (g_strcmp0 (greeting, "Return Unregistered") == 0)
      71                 :            :         {
      72                 :          0 :           g_dbus_method_invocation_return_error (invocation,
      73                 :            :                                                  G_IO_ERROR,
      74                 :            :                                                  G_IO_ERROR_FAILED_HANDLED,
      75                 :            :                                                  "As requested, here's a GError not registered (G_IO_ERROR_FAILED_HANDLED)");
      76                 :            :         }
      77         [ #  # ]:          0 :       else if (g_strcmp0 (greeting, "Return Registered") == 0)
      78                 :            :         {
      79                 :          0 :           g_dbus_method_invocation_return_error (invocation,
      80                 :            :                                                  G_DBUS_ERROR,
      81                 :            :                                                  G_DBUS_ERROR_MATCH_RULE_NOT_FOUND,
      82                 :            :                                                  "As requested, here's a GError that is registered (G_DBUS_ERROR_MATCH_RULE_NOT_FOUND)");
      83                 :            :         }
      84         [ #  # ]:          0 :       else if (g_strcmp0 (greeting, "Return Raw") == 0)
      85                 :            :         {
      86                 :          0 :           g_dbus_method_invocation_return_dbus_error (invocation,
      87                 :            :                                                       "org.gtk.GDBus.SomeErrorName",
      88                 :            :                                                       "As requested, here's a raw D-Bus error");
      89                 :            :         }
      90                 :            :       else
      91                 :            :         {
      92                 :            :           gchar *response;
      93                 :          0 :           response = g_strdup_printf ("You greeted me with '%s'. Thanks!", greeting);
      94                 :          0 :           g_dbus_method_invocation_return_value (invocation,
      95                 :            :                                                  g_variant_new ("(s)", response));
      96                 :          0 :           g_free (response);
      97                 :            :         }
      98                 :            :     }
      99         [ #  # ]:          0 :   else if (g_strcmp0 (method_name, "EmitSignal") == 0)
     100                 :            :     {
     101                 :            :       GError *local_error;
     102                 :            :       gdouble speed_in_mph;
     103                 :            :       gchar *speed_as_string;
     104                 :            : 
     105                 :          0 :       g_variant_get (parameters, "(d)", &speed_in_mph);
     106                 :          0 :       speed_as_string = g_strdup_printf ("%g mph!", speed_in_mph);
     107                 :            : 
     108                 :          0 :       local_error = NULL;
     109                 :          0 :       g_dbus_connection_emit_signal (connection,
     110                 :            :                                      NULL,
     111                 :            :                                      object_path,
     112                 :            :                                      interface_name,
     113                 :            :                                      "VelocityChanged",
     114                 :            :                                      g_variant_new ("(ds)",
     115                 :            :                                                     speed_in_mph,
     116                 :            :                                                     speed_as_string),
     117                 :            :                                      &local_error);
     118                 :          0 :       g_assert_no_error (local_error);
     119                 :          0 :       g_free (speed_as_string);
     120                 :            : 
     121                 :          0 :       g_dbus_method_invocation_return_value (invocation, NULL);
     122                 :            :     }
     123         [ #  # ]:          0 :   else if (g_strcmp0 (method_name, "GimmeStdout") == 0)
     124                 :            :     {
     125                 :            : #ifdef G_OS_UNIX
     126         [ #  # ]:          0 :       if (g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING)
     127                 :            :         {
     128                 :            :           GDBusMessage *reply;
     129                 :            :           GUnixFDList *fd_list;
     130                 :            :           GError *error;
     131                 :            : 
     132                 :          0 :           fd_list = g_unix_fd_list_new ();
     133                 :          0 :           error = NULL;
     134                 :          0 :           g_unix_fd_list_append (fd_list, STDOUT_FILENO, &error);
     135                 :          0 :           g_assert_no_error (error);
     136                 :            : 
     137                 :          0 :           reply = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation));
     138                 :          0 :           g_dbus_message_set_unix_fd_list (reply, fd_list);
     139                 :            : 
     140                 :          0 :           error = NULL;
     141                 :          0 :           g_dbus_connection_send_message (connection,
     142                 :            :                                           reply,
     143                 :            :                                           G_DBUS_SEND_MESSAGE_FLAGS_NONE,
     144                 :            :                                           NULL, /* out_serial */
     145                 :            :                                           &error);
     146                 :          0 :           g_assert_no_error (error);
     147                 :            : 
     148                 :          0 :           g_object_unref (invocation);
     149                 :          0 :           g_object_unref (fd_list);
     150                 :          0 :           g_object_unref (reply);
     151                 :            :         }
     152                 :            :       else
     153                 :            :         {
     154                 :          0 :           g_dbus_method_invocation_return_dbus_error (invocation,
     155                 :            :                                                       "org.gtk.GDBus.Failed",
     156                 :            :                                                       "Your message bus daemon does not support file descriptor passing (need D-Bus >= 1.3.0)");
     157                 :            :         }
     158                 :            : #else
     159                 :            :       g_dbus_method_invocation_return_dbus_error (invocation,
     160                 :            :                                                   "org.gtk.GDBus.NotOnUnix",
     161                 :            :                                                   "Your OS does not support file descriptor passing");
     162                 :            : #endif
     163                 :            :     }
     164                 :          0 : }
     165                 :            : 
     166                 :            : static gchar *_global_title = NULL;
     167                 :            : 
     168                 :            : static gboolean swap_a_and_b = FALSE;
     169                 :            : 
     170                 :            : static GVariant *
     171                 :          0 : handle_get_property (GDBusConnection  *connection,
     172                 :            :                      const gchar      *sender,
     173                 :            :                      const gchar      *object_path,
     174                 :            :                      const gchar      *interface_name,
     175                 :            :                      const gchar      *property_name,
     176                 :            :                      GError          **error,
     177                 :            :                      gpointer          user_data)
     178                 :            : {
     179                 :            :   GVariant *ret;
     180                 :            : 
     181                 :          0 :   ret = NULL;
     182         [ #  # ]:          0 :   if (g_strcmp0 (property_name, "FluxCapicitorName") == 0)
     183                 :            :     {
     184                 :          0 :       ret = g_variant_new_string ("DeLorean");
     185                 :            :     }
     186         [ #  # ]:          0 :   else if (g_strcmp0 (property_name, "Title") == 0)
     187                 :            :     {
     188         [ #  # ]:          0 :       if (_global_title == NULL)
     189                 :          0 :         _global_title = g_strdup ("Back To C!");
     190                 :          0 :       ret = g_variant_new_string (_global_title);
     191                 :            :     }
     192         [ #  # ]:          0 :   else if (g_strcmp0 (property_name, "ReadingAlwaysThrowsError") == 0)
     193                 :            :     {
     194                 :          0 :       g_set_error (error,
     195                 :            :                    G_IO_ERROR,
     196                 :            :                    G_IO_ERROR_FAILED,
     197                 :            :                    "Hello %s. I thought I said reading this property "
     198                 :            :                    "always results in an error. kthxbye",
     199                 :            :                    sender);
     200                 :            :     }
     201         [ #  # ]:          0 :   else if (g_strcmp0 (property_name, "WritingAlwaysThrowsError") == 0)
     202                 :            :     {
     203                 :          0 :       ret = g_variant_new_string ("There's no home like home");
     204                 :            :     }
     205         [ #  # ]:          0 :   else if (g_strcmp0 (property_name, "Foo") == 0)
     206                 :            :     {
     207         [ #  # ]:          0 :       ret = g_variant_new_string (swap_a_and_b ? "Tock" : "Tick");
     208                 :            :     }
     209         [ #  # ]:          0 :   else if (g_strcmp0 (property_name, "Bar") == 0)
     210                 :            :     {
     211         [ #  # ]:          0 :       ret = g_variant_new_string (swap_a_and_b ? "Tick" : "Tock");
     212                 :            :     }
     213                 :            : 
     214                 :          0 :   return ret;
     215                 :            : }
     216                 :            : 
     217                 :            : static gboolean
     218                 :          0 : handle_set_property (GDBusConnection  *connection,
     219                 :            :                      const gchar      *sender,
     220                 :            :                      const gchar      *object_path,
     221                 :            :                      const gchar      *interface_name,
     222                 :            :                      const gchar      *property_name,
     223                 :            :                      GVariant         *value,
     224                 :            :                      GError          **error,
     225                 :            :                      gpointer          user_data)
     226                 :            : {
     227         [ #  # ]:          0 :   if (g_strcmp0 (property_name, "Title") == 0)
     228                 :            :     {
     229         [ #  # ]:          0 :       if (g_strcmp0 (_global_title, g_variant_get_string (value, NULL)) != 0)
     230                 :            :         {
     231                 :            :           GVariantBuilder *builder;
     232                 :            :           GError *local_error;
     233                 :            : 
     234                 :          0 :           g_free (_global_title);
     235                 :          0 :           _global_title = g_variant_dup_string (value, NULL);
     236                 :            : 
     237                 :          0 :           local_error = NULL;
     238                 :          0 :           builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
     239                 :          0 :           g_variant_builder_add (builder,
     240                 :            :                                  "{sv}",
     241                 :            :                                  "Title",
     242                 :            :                                  g_variant_new_string (_global_title));
     243                 :          0 :           g_dbus_connection_emit_signal (connection,
     244                 :            :                                          NULL,
     245                 :            :                                          object_path,
     246                 :            :                                          "org.freedesktop.DBus.Properties",
     247                 :            :                                          "PropertiesChanged",
     248                 :            :                                          g_variant_new ("(sa{sv}as)",
     249                 :            :                                                         interface_name,
     250                 :            :                                                         builder,
     251                 :            :                                                         NULL),
     252                 :            :                                          &local_error);
     253                 :          0 :           g_assert_no_error (local_error);
     254                 :            :         }
     255                 :            :     }
     256         [ #  # ]:          0 :   else if (g_strcmp0 (property_name, "ReadingAlwaysThrowsError") == 0)
     257                 :            :     {
     258                 :            :       /* do nothing - they can't read it after all! */
     259                 :            :     }
     260         [ #  # ]:          0 :   else if (g_strcmp0 (property_name, "WritingAlwaysThrowsError") == 0)
     261                 :            :     {
     262                 :          0 :       g_set_error (error,
     263                 :            :                    G_IO_ERROR,
     264                 :            :                    G_IO_ERROR_FAILED,
     265                 :            :                    "Hello AGAIN %s. I thought I said writing this property "
     266                 :            :                    "always results in an error. kthxbye",
     267                 :            :                    sender);
     268                 :            :     }
     269                 :            : 
     270                 :          0 :   return *error == NULL;
     271                 :            : }
     272                 :            : 
     273                 :            : 
     274                 :            : /* for now */
     275                 :            : static const GDBusInterfaceVTable interface_vtable =
     276                 :            : {
     277                 :            :   handle_method_call,
     278                 :            :   handle_get_property,
     279                 :            :   handle_set_property,
     280                 :            :   { 0 }
     281                 :            : };
     282                 :            : 
     283                 :            : /* ---------------------------------------------------------------------------------------------------- */
     284                 :            : 
     285                 :            : static gboolean
     286                 :          0 : on_timeout_cb (gpointer user_data)
     287                 :            : {
     288                 :          0 :   GDBusConnection *connection = G_DBUS_CONNECTION (user_data);
     289                 :            :   GVariantBuilder *builder;
     290                 :            :   GVariantBuilder *invalidated_builder;
     291                 :            :   GError *error;
     292                 :            : 
     293                 :          0 :   swap_a_and_b = !swap_a_and_b;
     294                 :            : 
     295                 :          0 :   error = NULL;
     296                 :          0 :   builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
     297                 :          0 :   invalidated_builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
     298                 :          0 :   g_variant_builder_add (builder,
     299                 :            :                          "{sv}",
     300                 :            :                          "Foo",
     301         [ #  # ]:          0 :                          g_variant_new_string (swap_a_and_b ? "Tock" : "Tick"));
     302                 :          0 :   g_variant_builder_add (builder,
     303                 :            :                          "{sv}",
     304                 :            :                          "Bar",
     305         [ #  # ]:          0 :                          g_variant_new_string (swap_a_and_b ? "Tick" : "Tock"));
     306                 :          0 :   g_dbus_connection_emit_signal (connection,
     307                 :            :                                  NULL,
     308                 :            :                                  "/org/gtk/GDBus/TestObject",
     309                 :            :                                  "org.freedesktop.DBus.Properties",
     310                 :            :                                  "PropertiesChanged",
     311                 :            :                                  g_variant_new ("(sa{sv}as)",
     312                 :            :                                                 "org.gtk.GDBus.TestInterface",
     313                 :            :                                                 builder,
     314                 :            :                                                 invalidated_builder),
     315                 :            :                                  &error);
     316                 :          0 :   g_assert_no_error (error);
     317                 :            : 
     318                 :            : 
     319                 :          0 :   return G_SOURCE_CONTINUE;
     320                 :            : }
     321                 :            : 
     322                 :            : /* ---------------------------------------------------------------------------------------------------- */
     323                 :            : 
     324                 :            : static void
     325                 :          0 : on_bus_acquired (GDBusConnection *connection,
     326                 :            :                  const gchar     *name,
     327                 :            :                  gpointer         user_data)
     328                 :            : {
     329                 :            :   guint registration_id;
     330                 :            : 
     331                 :          0 :   registration_id = g_dbus_connection_register_object (connection,
     332                 :            :                                                        "/org/gtk/GDBus/TestObject",
     333                 :          0 :                                                        introspection_data->interfaces[0],
     334                 :            :                                                        &interface_vtable,
     335                 :            :                                                        NULL,  /* user_data */
     336                 :            :                                                        NULL,  /* user_data_free_func */
     337                 :            :                                                        NULL); /* GError** */
     338                 :          0 :   g_assert (registration_id > 0);
     339                 :            : 
     340                 :            :   /* swap value of properties Foo and Bar every two seconds */
     341                 :          0 :   g_timeout_add_seconds (2,
     342                 :            :                          on_timeout_cb,
     343                 :            :                          connection);
     344                 :          0 : }
     345                 :            : 
     346                 :            : static void
     347                 :          0 : on_name_acquired (GDBusConnection *connection,
     348                 :            :                   const gchar     *name,
     349                 :            :                   gpointer         user_data)
     350                 :            : {
     351                 :          0 : }
     352                 :            : 
     353                 :            : static void
     354                 :          0 : on_name_lost (GDBusConnection *connection,
     355                 :            :               const gchar     *name,
     356                 :            :               gpointer         user_data)
     357                 :            : {
     358                 :          0 :   exit (1);
     359                 :            : }
     360                 :            : 
     361                 :            : int
     362                 :          0 : main (int argc, char *argv[])
     363                 :            : {
     364                 :            :   guint owner_id;
     365                 :            :   GMainLoop *loop;
     366                 :            : 
     367                 :            :   /* We are lazy here - we don't want to manually provide
     368                 :            :    * the introspection data structures - so we just build
     369                 :            :    * them from XML.
     370                 :            :    */
     371                 :          0 :   introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
     372                 :          0 :   g_assert (introspection_data != NULL);
     373                 :            : 
     374                 :          0 :   owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
     375                 :            :                              "org.gtk.GDBus.TestServer",
     376                 :            :                              G_BUS_NAME_OWNER_FLAGS_NONE,
     377                 :            :                              on_bus_acquired,
     378                 :            :                              on_name_acquired,
     379                 :            :                              on_name_lost,
     380                 :            :                              NULL,
     381                 :            :                              NULL);
     382                 :            : 
     383                 :          0 :   loop = g_main_loop_new (NULL, FALSE);
     384                 :          0 :   g_main_loop_run (loop);
     385                 :            : 
     386                 :          0 :   g_bus_unown_name (owner_id);
     387                 :            : 
     388                 :          0 :   g_dbus_node_info_unref (introspection_data);
     389                 :            : 
     390                 :          0 :   return 0;
     391                 :            : }

Generated by: LCOV version 1.14