LCOV - code coverage report
Current view: top level - gio - gdbusmethodinvocation.c (source / functions) Coverage Total Hit
Test: unnamed Lines: 95.0 % 180 171
Test Date: 2024-11-26 05:23:01 Functions: 100.0 % 26 26
Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* GDBus - GLib D-Bus Library
       2                 :             :  *
       3                 :             :  * Copyright (C) 2008-2010 Red Hat, Inc.
       4                 :             :  *
       5                 :             :  * SPDX-License-Identifier: LGPL-2.1-or-later
       6                 :             :  *
       7                 :             :  * This library is free software; you can redistribute it and/or
       8                 :             :  * modify it under the terms of the GNU Lesser General Public
       9                 :             :  * License as published by the Free Software Foundation; either
      10                 :             :  * version 2.1 of the License, or (at your option) any later version.
      11                 :             :  *
      12                 :             :  * This library is distributed in the hope that it will be useful,
      13                 :             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15                 :             :  * Lesser General Public License for more details.
      16                 :             :  *
      17                 :             :  * You should have received a copy of the GNU Lesser General
      18                 :             :  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      19                 :             :  *
      20                 :             :  * Author: David Zeuthen <davidz@redhat.com>
      21                 :             :  */
      22                 :             : 
      23                 :             : #include "config.h"
      24                 :             : 
      25                 :             : #include <stdlib.h>
      26                 :             : 
      27                 :             : #include "gdbusutils.h"
      28                 :             : #include "gdbusconnection.h"
      29                 :             : #include "gdbusmessage.h"
      30                 :             : #include "gdbusmethodinvocation.h"
      31                 :             : #include "gdbusintrospection.h"
      32                 :             : #include "gdbuserror.h"
      33                 :             : #include "gdbusprivate.h"
      34                 :             : #include "gioerror.h"
      35                 :             : 
      36                 :             : #ifdef G_OS_UNIX
      37                 :             : #include "gunixfdlist.h"
      38                 :             : #endif
      39                 :             : 
      40                 :             : #include "glibintl.h"
      41                 :             : 
      42                 :             : /**
      43                 :             :  * GDBusMethodInvocation:
      44                 :             :  *
      45                 :             :  * Instances of the `GDBusMethodInvocation` class are used when
      46                 :             :  * handling D-Bus method calls. It provides a way to asynchronously
      47                 :             :  * return results and errors.
      48                 :             :  *
      49                 :             :  * The normal way to obtain a `GDBusMethodInvocation` object is to receive
      50                 :             :  * it as an argument to the `handle_method_call()` function in a
      51                 :             :  * [type@Gio.DBusInterfaceVTable] that was passed to
      52                 :             :  * [method@Gio.DBusConnection.register_object].
      53                 :             :  *
      54                 :             :  * Since: 2.26
      55                 :             :  */
      56                 :             : 
      57                 :             : typedef struct _GDBusMethodInvocationClass GDBusMethodInvocationClass;
      58                 :             : 
      59                 :             : /**
      60                 :             :  * GDBusMethodInvocationClass:
      61                 :             :  *
      62                 :             :  * Class structure for #GDBusMethodInvocation.
      63                 :             :  *
      64                 :             :  * Since: 2.26
      65                 :             :  */
      66                 :             : struct _GDBusMethodInvocationClass
      67                 :             : {
      68                 :             :   /*< private >*/
      69                 :             :   GObjectClass parent_class;
      70                 :             : };
      71                 :             : 
      72                 :             : struct _GDBusMethodInvocation
      73                 :             : {
      74                 :             :   /*< private >*/
      75                 :             :   GObject parent_instance;
      76                 :             : 
      77                 :             :   /* construct-only properties */
      78                 :             :   gchar           *sender;
      79                 :             :   gchar           *object_path;
      80                 :             :   gchar           *interface_name;
      81                 :             :   gchar           *method_name;
      82                 :             :   GDBusMethodInfo *method_info;
      83                 :             :   GDBusPropertyInfo *property_info;
      84                 :             :   GDBusConnection *connection;
      85                 :             :   GDBusMessage    *message;
      86                 :             :   GVariant        *parameters;
      87                 :             :   gpointer         user_data;
      88                 :             : };
      89                 :             : 
      90                 :       13140 : G_DEFINE_TYPE (GDBusMethodInvocation, g_dbus_method_invocation, G_TYPE_OBJECT)
      91                 :             : 
      92                 :             : static void
      93                 :         952 : g_dbus_method_invocation_finalize (GObject *object)
      94                 :             : {
      95                 :         952 :   GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (object);
      96                 :             : 
      97                 :         952 :   g_free (invocation->sender);
      98                 :         952 :   g_free (invocation->object_path);
      99                 :         952 :   g_free (invocation->interface_name);
     100                 :         952 :   g_free (invocation->method_name);
     101                 :         952 :   if (invocation->method_info)
     102                 :         937 :       g_dbus_method_info_unref (invocation->method_info);
     103                 :         952 :   if (invocation->property_info)
     104                 :          12 :       g_dbus_property_info_unref (invocation->property_info);
     105                 :         952 :   g_object_unref (invocation->connection);
     106                 :         952 :   g_object_unref (invocation->message);
     107                 :         952 :   g_variant_unref (invocation->parameters);
     108                 :             : 
     109                 :         952 :   G_OBJECT_CLASS (g_dbus_method_invocation_parent_class)->finalize (object);
     110                 :         952 : }
     111                 :             : 
     112                 :             : static void
     113                 :          22 : g_dbus_method_invocation_class_init (GDBusMethodInvocationClass *klass)
     114                 :             : {
     115                 :          22 :   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
     116                 :             : 
     117                 :          22 :   gobject_class->finalize = g_dbus_method_invocation_finalize;
     118                 :          22 : }
     119                 :             : 
     120                 :             : static void
     121                 :         953 : g_dbus_method_invocation_init (GDBusMethodInvocation *invocation)
     122                 :             : {
     123                 :         953 : }
     124                 :             : 
     125                 :             : /**
     126                 :             :  * g_dbus_method_invocation_get_sender:
     127                 :             :  * @invocation: A #GDBusMethodInvocation.
     128                 :             :  *
     129                 :             :  * Gets the bus name that invoked the method.
     130                 :             :  *
     131                 :             :  * Returns: A string. Do not free, it is owned by @invocation.
     132                 :             :  *
     133                 :             :  * Since: 2.26
     134                 :             :  */
     135                 :             : const gchar *
     136                 :         826 : g_dbus_method_invocation_get_sender (GDBusMethodInvocation *invocation)
     137                 :             : {
     138                 :         826 :   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
     139                 :         826 :   return invocation->sender;
     140                 :             : }
     141                 :             : 
     142                 :             : /**
     143                 :             :  * g_dbus_method_invocation_get_object_path:
     144                 :             :  * @invocation: A #GDBusMethodInvocation.
     145                 :             :  *
     146                 :             :  * Gets the object path the method was invoked on.
     147                 :             :  *
     148                 :             :  * Returns: A string. Do not free, it is owned by @invocation.
     149                 :             :  *
     150                 :             :  * Since: 2.26
     151                 :             :  */
     152                 :             : const gchar *
     153                 :         996 : g_dbus_method_invocation_get_object_path (GDBusMethodInvocation *invocation)
     154                 :             : {
     155                 :         996 :   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
     156                 :         996 :   return invocation->object_path;
     157                 :             : }
     158                 :             : 
     159                 :             : /**
     160                 :             :  * g_dbus_method_invocation_get_interface_name:
     161                 :             :  * @invocation: A #GDBusMethodInvocation.
     162                 :             :  *
     163                 :             :  * Gets the name of the D-Bus interface the method was invoked on.
     164                 :             :  *
     165                 :             :  * If this method call is a property Get, Set or GetAll call that has
     166                 :             :  * been redirected to the method call handler then
     167                 :             :  * "org.freedesktop.DBus.Properties" will be returned.  See
     168                 :             :  * #GDBusInterfaceVTable for more information.
     169                 :             :  *
     170                 :             :  * Returns: A string. Do not free, it is owned by @invocation.
     171                 :             :  *
     172                 :             :  * Since: 2.26
     173                 :             :  */
     174                 :             : const gchar *
     175                 :         999 : g_dbus_method_invocation_get_interface_name (GDBusMethodInvocation *invocation)
     176                 :             : {
     177                 :         999 :   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
     178                 :         999 :   return invocation->interface_name;
     179                 :             : }
     180                 :             : 
     181                 :             : /**
     182                 :             :  * g_dbus_method_invocation_get_method_info:
     183                 :             :  * @invocation: A #GDBusMethodInvocation.
     184                 :             :  *
     185                 :             :  * Gets information about the method call, if any.
     186                 :             :  *
     187                 :             :  * If this method invocation is a property Get, Set or GetAll call that
     188                 :             :  * has been redirected to the method call handler then %NULL will be
     189                 :             :  * returned.  See g_dbus_method_invocation_get_property_info() and
     190                 :             :  * #GDBusInterfaceVTable for more information.
     191                 :             :  *
     192                 :             :  * Returns: (nullable): A #GDBusMethodInfo or %NULL. Do not free, it is owned by @invocation.
     193                 :             :  *
     194                 :             :  * Since: 2.26
     195                 :             :  */
     196                 :             : const GDBusMethodInfo *
     197                 :          66 : g_dbus_method_invocation_get_method_info (GDBusMethodInvocation *invocation)
     198                 :             : {
     199                 :          66 :   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
     200                 :          66 :   return invocation->method_info;
     201                 :             : }
     202                 :             : 
     203                 :             : /**
     204                 :             :  * g_dbus_method_invocation_get_property_info:
     205                 :             :  * @invocation: A #GDBusMethodInvocation
     206                 :             :  *
     207                 :             :  * Gets information about the property that this method call is for, if
     208                 :             :  * any.
     209                 :             :  *
     210                 :             :  * This will only be set in the case of an invocation in response to a
     211                 :             :  * property Get or Set call that has been directed to the method call
     212                 :             :  * handler for an object on account of its property_get() or
     213                 :             :  * property_set() vtable pointers being unset.
     214                 :             :  *
     215                 :             :  * See #GDBusInterfaceVTable for more information.
     216                 :             :  *
     217                 :             :  * If the call was GetAll, %NULL will be returned.
     218                 :             :  *
     219                 :             :  * Returns: (nullable) (transfer none): a #GDBusPropertyInfo or %NULL
     220                 :             :  *
     221                 :             :  * Since: 2.38
     222                 :             :  */
     223                 :             : const GDBusPropertyInfo *
     224                 :           5 : g_dbus_method_invocation_get_property_info (GDBusMethodInvocation *invocation)
     225                 :             : {
     226                 :           5 :   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
     227                 :           5 :   return invocation->property_info;
     228                 :             : }
     229                 :             : 
     230                 :             : /**
     231                 :             :  * g_dbus_method_invocation_get_method_name:
     232                 :             :  * @invocation: A #GDBusMethodInvocation.
     233                 :             :  *
     234                 :             :  * Gets the name of the method that was invoked.
     235                 :             :  *
     236                 :             :  * Returns: A string. Do not free, it is owned by @invocation.
     237                 :             :  *
     238                 :             :  * Since: 2.26
     239                 :             :  */
     240                 :             : const gchar *
     241                 :         832 : g_dbus_method_invocation_get_method_name (GDBusMethodInvocation *invocation)
     242                 :             : {
     243                 :         832 :   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
     244                 :         832 :   return invocation->method_name;
     245                 :             : }
     246                 :             : 
     247                 :             : /**
     248                 :             :  * g_dbus_method_invocation_get_connection:
     249                 :             :  * @invocation: A #GDBusMethodInvocation.
     250                 :             :  *
     251                 :             :  * Gets the #GDBusConnection the method was invoked on.
     252                 :             :  *
     253                 :             :  * Returns: (transfer none):A #GDBusConnection. Do not free, it is owned by @invocation.
     254                 :             :  *
     255                 :             :  * Since: 2.26
     256                 :             :  */
     257                 :             : GDBusConnection *
     258                 :        2539 : g_dbus_method_invocation_get_connection (GDBusMethodInvocation *invocation)
     259                 :             : {
     260                 :        2539 :   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
     261                 :        2539 :   return invocation->connection;
     262                 :             : }
     263                 :             : 
     264                 :             : /**
     265                 :             :  * g_dbus_method_invocation_get_message:
     266                 :             :  * @invocation: A #GDBusMethodInvocation.
     267                 :             :  *
     268                 :             :  * Gets the #GDBusMessage for the method invocation. This is useful if
     269                 :             :  * you need to use low-level protocol features, such as UNIX file
     270                 :             :  * descriptor passing, that cannot be properly expressed in the
     271                 :             :  * #GVariant API.
     272                 :             :  *
     273                 :             :  * See this [server][gdbus-server] and [client][gdbus-unix-fd-client]
     274                 :             :  * for an example of how to use this low-level API to send and receive
     275                 :             :  * UNIX file descriptors.
     276                 :             :  *
     277                 :             :  * Returns: (transfer none): #GDBusMessage. Do not free, it is owned by @invocation.
     278                 :             :  *
     279                 :             :  * Since: 2.26
     280                 :             :  */
     281                 :             : GDBusMessage *
     282                 :         213 : g_dbus_method_invocation_get_message (GDBusMethodInvocation *invocation)
     283                 :             : {
     284                 :         213 :   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
     285                 :         213 :   return invocation->message;
     286                 :             : }
     287                 :             : 
     288                 :             : /**
     289                 :             :  * g_dbus_method_invocation_get_parameters:
     290                 :             :  * @invocation: A #GDBusMethodInvocation.
     291                 :             :  *
     292                 :             :  * Gets the parameters of the method invocation. If there are no input
     293                 :             :  * parameters then this will return a GVariant with 0 children rather than NULL.
     294                 :             :  *
     295                 :             :  * Returns: (transfer none): A #GVariant tuple. Do not unref this because it is owned by @invocation.
     296                 :             :  *
     297                 :             :  * Since: 2.26
     298                 :             :  */
     299                 :             : GVariant *
     300                 :         821 : g_dbus_method_invocation_get_parameters (GDBusMethodInvocation *invocation)
     301                 :             : {
     302                 :         821 :   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
     303                 :         821 :   return invocation->parameters;
     304                 :             : }
     305                 :             : 
     306                 :             : /**
     307                 :             :  * g_dbus_method_invocation_get_user_data: (skip)
     308                 :             :  * @invocation: A #GDBusMethodInvocation.
     309                 :             :  *
     310                 :             :  * Gets the @user_data #gpointer passed to g_dbus_connection_register_object().
     311                 :             :  *
     312                 :             :  * Returns: A #gpointer.
     313                 :             :  *
     314                 :             :  * Since: 2.26
     315                 :             :  */
     316                 :             : gpointer
     317                 :         814 : g_dbus_method_invocation_get_user_data (GDBusMethodInvocation *invocation)
     318                 :             : {
     319                 :         814 :   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
     320                 :         814 :   return invocation->user_data;
     321                 :             : }
     322                 :             : 
     323                 :             : /* < internal >
     324                 :             :  * _g_dbus_method_invocation_new:
     325                 :             :  * @sender: (nullable): The bus name that invoked the method or %NULL if @connection is not a bus connection.
     326                 :             :  * @object_path: The object path the method was invoked on.
     327                 :             :  * @interface_name: The name of the D-Bus interface the method was invoked on.
     328                 :             :  * @method_name: The name of the method that was invoked.
     329                 :             :  * @method_info: (nullable): Information about the method call or %NULL.
     330                 :             :  * @property_info: (nullable): Information about the property or %NULL.
     331                 :             :  * @connection: The #GDBusConnection the method was invoked on.
     332                 :             :  * @message: The D-Bus message as a #GDBusMessage.
     333                 :             :  * @parameters: The parameters as a #GVariant tuple.
     334                 :             :  * @user_data: The @user_data #gpointer passed to g_dbus_connection_register_object().
     335                 :             :  *
     336                 :             :  * Creates a new #GDBusMethodInvocation object.
     337                 :             :  *
     338                 :             :  * Returns: A #GDBusMethodInvocation. Free with g_object_unref().
     339                 :             :  *
     340                 :             :  * Since: 2.26
     341                 :             :  */
     342                 :             : GDBusMethodInvocation *
     343                 :         953 : _g_dbus_method_invocation_new (const gchar             *sender,
     344                 :             :                                const gchar             *object_path,
     345                 :             :                                const gchar             *interface_name,
     346                 :             :                                const gchar             *method_name,
     347                 :             :                                const GDBusMethodInfo   *method_info,
     348                 :             :                                const GDBusPropertyInfo *property_info,
     349                 :             :                                GDBusConnection         *connection,
     350                 :             :                                GDBusMessage            *message,
     351                 :             :                                GVariant                *parameters,
     352                 :             :                                gpointer                 user_data)
     353                 :             : {
     354                 :             :   GDBusMethodInvocation *invocation;
     355                 :             : 
     356                 :         953 :   g_return_val_if_fail (sender == NULL || g_dbus_is_name (sender), NULL);
     357                 :         953 :   g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
     358                 :         953 :   g_return_val_if_fail (interface_name == NULL || g_dbus_is_interface_name (interface_name), NULL);
     359                 :         953 :   g_return_val_if_fail (g_dbus_is_member_name (method_name), NULL);
     360                 :         953 :   g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
     361                 :         953 :   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
     362                 :         953 :   g_return_val_if_fail (g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE), NULL);
     363                 :             : 
     364                 :         953 :   invocation = G_DBUS_METHOD_INVOCATION (g_object_new (G_TYPE_DBUS_METHOD_INVOCATION, NULL));
     365                 :         953 :   invocation->sender = g_strdup (sender);
     366                 :         953 :   invocation->object_path = g_strdup (object_path);
     367                 :         953 :   invocation->interface_name = g_strdup (interface_name);
     368                 :         953 :   invocation->method_name = g_strdup (method_name);
     369                 :         953 :   if (method_info)
     370                 :         938 :     invocation->method_info = g_dbus_method_info_ref ((GDBusMethodInfo *)method_info);
     371                 :         953 :   if (property_info)
     372                 :          12 :     invocation->property_info = g_dbus_property_info_ref ((GDBusPropertyInfo *)property_info);
     373                 :         953 :   invocation->connection = g_object_ref (connection);
     374                 :         953 :   invocation->message = g_object_ref (message);
     375                 :         953 :   invocation->parameters = g_variant_ref (parameters);
     376                 :         953 :   invocation->user_data = user_data;
     377                 :             : 
     378                 :         953 :   return invocation;
     379                 :             : }
     380                 :             : 
     381                 :             : /* ---------------------------------------------------------------------------------------------------- */
     382                 :             : 
     383                 :             : static void
     384                 :         733 : g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocation,
     385                 :             :                                                 GVariant              *parameters,
     386                 :             :                                                 GUnixFDList           *fd_list)
     387                 :             : {
     388                 :             :   GDBusMessage *reply;
     389                 :             :   GError *error;
     390                 :             : 
     391                 :         733 :   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
     392                 :         733 :   g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));
     393                 :             : 
     394                 :         733 :   if (g_dbus_message_get_flags (invocation->message) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED)
     395                 :         179 :     goto out;
     396                 :             : 
     397                 :         554 :   if (parameters == NULL)
     398                 :          97 :     parameters = g_variant_new_tuple (NULL, 0);
     399                 :             : 
     400                 :             :   /* if we have introspection data, check that the signature of @parameters is correct */
     401                 :         554 :   if (invocation->method_info != NULL)
     402                 :             :     {
     403                 :             :       GVariantType *type;
     404                 :             : 
     405                 :         544 :       type = _g_dbus_compute_complete_signature (invocation->method_info->out_args);
     406                 :             : 
     407                 :         544 :       if (!g_variant_is_of_type (parameters, type))
     408                 :             :         {
     409                 :           1 :           gchar *type_string = g_variant_type_dup_string (type);
     410                 :             : 
     411                 :           1 :           g_warning ("Type of return value is incorrect: expected '%s', got '%s'",
     412                 :             :                      type_string, g_variant_get_type_string (parameters));
     413                 :           1 :           g_variant_type_free (type);
     414                 :           1 :           g_free (type_string);
     415                 :           1 :           goto out;
     416                 :             :         }
     417                 :         543 :       g_variant_type_free (type);
     418                 :             :     }
     419                 :             : 
     420                 :             :   /* property_info is only non-NULL if set that way from
     421                 :             :    * GDBusConnection, so this must be the case of async property
     422                 :             :    * handling on either 'Get' or 'Set'.
     423                 :             :    *
     424                 :             :    * property_info is NULL for 'GetAll'.
     425                 :             :    */
     426                 :         553 :   if (invocation->property_info != NULL)
     427                 :             :     {
     428                 :           8 :       if (g_str_equal (invocation->method_name, "Get"))
     429                 :             :         {
     430                 :             :           GVariant *nested;
     431                 :             : 
     432                 :           5 :           if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(v)")))
     433                 :             :             {
     434                 :           2 :               g_warning ("Type of return value for property 'Get' call should be '(v)' but got '%s'",
     435                 :             :                          g_variant_get_type_string (parameters));
     436                 :           3 :               goto out;
     437                 :             :             }
     438                 :             : 
     439                 :             :           /* Go deeper and make sure that the value inside of the
     440                 :             :            * variant matches the property type.
     441                 :             :            */
     442                 :           3 :           g_variant_get (parameters, "(v)", &nested);
     443                 :           3 :           if (!g_str_equal (g_variant_get_type_string (nested), invocation->property_info->signature))
     444                 :             :             {
     445                 :           1 :               g_warning ("Value returned from property 'Get' call for '%s' should be '%s' but is '%s'",
     446                 :             :                          invocation->property_info->name, invocation->property_info->signature,
     447                 :             :                          g_variant_get_type_string (nested));
     448                 :           1 :               g_variant_unref (nested);
     449                 :           1 :               goto out;
     450                 :             :             }
     451                 :           2 :           g_variant_unref (nested);
     452                 :             :         }
     453                 :             : 
     454                 :           3 :       else if (g_str_equal (invocation->method_name, "Set"))
     455                 :             :         {
     456                 :           3 :           if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE_UNIT))
     457                 :             :             {
     458                 :           1 :               g_warning ("Type of return value for property 'Set' call should be '()' but got '%s'",
     459                 :             :                          g_variant_get_type_string (parameters));
     460                 :           1 :               goto out;
     461                 :             :             }
     462                 :             :         }
     463                 :             : 
     464                 :             :       else
     465                 :             :         g_assert_not_reached ();
     466                 :             :     }
     467                 :         545 :   else if (g_str_equal (invocation->interface_name, DBUS_INTERFACE_PROPERTIES) &&
     468                 :           2 :            g_str_equal (invocation->method_name, "GetAll"))
     469                 :             :     {
     470                 :           2 :       if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a{sv})")))
     471                 :             :         {
     472                 :           1 :           g_warning ("Type of return value for property 'GetAll' call should be '(a{sv})' but got '%s'",
     473                 :             :                      g_variant_get_type_string (parameters));
     474                 :           1 :           goto out;
     475                 :             :         }
     476                 :             : 
     477                 :             :       /* Could iterate the list of properties and make sure that all
     478                 :             :        * of them are actually on the interface and with the correct
     479                 :             :        * types, but let's not do that for now...
     480                 :             :        */
     481                 :             :     }
     482                 :             : 
     483                 :         548 :   if (G_UNLIKELY (_g_dbus_debug_return ()))
     484                 :             :     {
     485                 :           0 :       _g_dbus_debug_print_lock ();
     486                 :           0 :       g_print ("========================================================================\n"
     487                 :             :                "GDBus-debug:Return:\n"
     488                 :             :                " >>>> METHOD RETURN\n"
     489                 :             :                "      in response to %s.%s()\n"
     490                 :             :                "      on object %s\n"
     491                 :             :                "      to name %s\n"
     492                 :             :                "      reply-serial %d\n",
     493                 :             :                invocation->interface_name, invocation->method_name,
     494                 :             :                invocation->object_path,
     495                 :             :                invocation->sender,
     496                 :             :                g_dbus_message_get_serial (invocation->message));
     497                 :           0 :       _g_dbus_debug_print_unlock ();
     498                 :             :     }
     499                 :             : 
     500                 :         548 :   reply = g_dbus_message_new_method_reply (invocation->message);
     501                 :         548 :   g_dbus_message_set_body (reply, g_steal_pointer (&parameters));
     502                 :             : 
     503                 :             : #ifdef G_OS_UNIX
     504                 :         548 :   if (fd_list != NULL)
     505                 :           5 :     g_dbus_message_set_unix_fd_list (reply, fd_list);
     506                 :             : #endif
     507                 :             : 
     508                 :         548 :   error = NULL;
     509                 :         548 :   if (!g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error))
     510                 :             :     {
     511                 :           0 :       if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED))
     512                 :           0 :         g_warning ("Error sending message: %s", error->message);
     513                 :           0 :       g_error_free (error);
     514                 :             :     }
     515                 :         548 :   g_object_unref (reply);
     516                 :             : 
     517                 :         733 :  out:
     518                 :         733 :   if (parameters != NULL)
     519                 :             :     {
     520                 :          13 :       g_variant_ref_sink (parameters);
     521                 :          13 :       g_variant_unref (parameters);
     522                 :             :     }
     523                 :             : 
     524                 :         733 :   g_object_unref (invocation);
     525                 :             : }
     526                 :             : 
     527                 :             : /**
     528                 :             :  * g_dbus_method_invocation_return_value:
     529                 :             :  * @invocation: (transfer full): A #GDBusMethodInvocation.
     530                 :             :  * @parameters: (nullable): A #GVariant tuple with out parameters for the method or %NULL if not passing any parameters.
     531                 :             :  *
     532                 :             :  * Finishes handling a D-Bus method call by returning @parameters.
     533                 :             :  * If the @parameters GVariant is floating, it is consumed.
     534                 :             :  *
     535                 :             :  * It is an error if @parameters is not of the right format: it must be a tuple
     536                 :             :  * containing the out-parameters of the D-Bus method. Even if the method has a
     537                 :             :  * single out-parameter, it must be contained in a tuple. If the method has no
     538                 :             :  * out-parameters, @parameters may be %NULL or an empty tuple.
     539                 :             :  *
     540                 :             :  * |[<!-- language="C" -->
     541                 :             :  * GDBusMethodInvocation *invocation = some_invocation;
     542                 :             :  * g_autofree gchar *result_string = NULL;
     543                 :             :  * g_autoptr (GError) error = NULL;
     544                 :             :  *
     545                 :             :  * result_string = calculate_result (&error);
     546                 :             :  *
     547                 :             :  * if (error != NULL)
     548                 :             :  *   g_dbus_method_invocation_return_gerror (invocation, error);
     549                 :             :  * else
     550                 :             :  *   g_dbus_method_invocation_return_value (invocation,
     551                 :             :  *                                          g_variant_new ("(s)", result_string));
     552                 :             :  *
     553                 :             :  * // Do not free @invocation here; returning a value does that
     554                 :             :  * ]|
     555                 :             :  *
     556                 :             :  * This method will take ownership of @invocation. See
     557                 :             :  * #GDBusInterfaceVTable for more information about the ownership of
     558                 :             :  * @invocation.
     559                 :             :  *
     560                 :             :  * Since 2.48, if the method call requested for a reply not to be sent
     561                 :             :  * then this call will sink @parameters and free @invocation, but
     562                 :             :  * otherwise do nothing (as per the recommendations of the D-Bus
     563                 :             :  * specification).
     564                 :             :  *
     565                 :             :  * Since: 2.26
     566                 :             :  */
     567                 :             : void
     568                 :         721 : g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation,
     569                 :             :                                        GVariant              *parameters)
     570                 :             : {
     571                 :         721 :   g_dbus_method_invocation_return_value_internal (invocation, parameters, NULL);
     572                 :         721 : }
     573                 :             : 
     574                 :             : #ifdef G_OS_UNIX
     575                 :             : /**
     576                 :             :  * g_dbus_method_invocation_return_value_with_unix_fd_list:
     577                 :             :  * @invocation: (transfer full): A #GDBusMethodInvocation.
     578                 :             :  * @parameters: (nullable): A #GVariant tuple with out parameters for the method or %NULL if not passing any parameters.
     579                 :             :  * @fd_list: (nullable): A #GUnixFDList or %NULL.
     580                 :             :  *
     581                 :             :  * Like g_dbus_method_invocation_return_value() but also takes a #GUnixFDList.
     582                 :             :  *
     583                 :             :  * This method is only available on UNIX.
     584                 :             :  *
     585                 :             :  * This method will take ownership of @invocation. See
     586                 :             :  * #GDBusInterfaceVTable for more information about the ownership of
     587                 :             :  * @invocation.
     588                 :             :  *
     589                 :             :  * Since: 2.30
     590                 :             :  */
     591                 :             : void
     592                 :          12 : g_dbus_method_invocation_return_value_with_unix_fd_list (GDBusMethodInvocation *invocation,
     593                 :             :                                                          GVariant              *parameters,
     594                 :             :                                                          GUnixFDList           *fd_list)
     595                 :             : {
     596                 :          12 :   g_dbus_method_invocation_return_value_internal (invocation, parameters, fd_list);
     597                 :          12 : }
     598                 :             : #endif
     599                 :             : 
     600                 :             : /* ---------------------------------------------------------------------------------------------------- */
     601                 :             : 
     602                 :             : /**
     603                 :             :  * g_dbus_method_invocation_return_error:
     604                 :             :  * @invocation: (transfer full): A #GDBusMethodInvocation.
     605                 :             :  * @domain: A #GQuark for the #GError error domain.
     606                 :             :  * @code: The error code.
     607                 :             :  * @format: printf()-style format.
     608                 :             :  * @...: Parameters for @format.
     609                 :             :  *
     610                 :             :  * Finishes handling a D-Bus method call by returning an error.
     611                 :             :  *
     612                 :             :  * See g_dbus_error_encode_gerror() for details about what error name
     613                 :             :  * will be returned on the wire. In a nutshell, if the given error is
     614                 :             :  * registered using g_dbus_error_register_error() the name given
     615                 :             :  * during registration is used. Otherwise, a name of the form
     616                 :             :  * `org.gtk.GDBus.UnmappedGError.Quark...` is used. This provides
     617                 :             :  * transparent mapping of #GError between applications using GDBus.
     618                 :             :  *
     619                 :             :  * If you are writing an application intended to be portable,
     620                 :             :  * always register errors with g_dbus_error_register_error()
     621                 :             :  * or use g_dbus_method_invocation_return_dbus_error().
     622                 :             :  *
     623                 :             :  * This method will take ownership of @invocation. See
     624                 :             :  * #GDBusInterfaceVTable for more information about the ownership of
     625                 :             :  * @invocation.
     626                 :             :  *
     627                 :             :  * Since 2.48, if the method call requested for a reply not to be sent
     628                 :             :  * then this call will free @invocation but otherwise do nothing (as per
     629                 :             :  * the recommendations of the D-Bus specification).
     630                 :             :  *
     631                 :             :  * Since: 2.26
     632                 :             :  */
     633                 :             : void
     634                 :          23 : g_dbus_method_invocation_return_error (GDBusMethodInvocation *invocation,
     635                 :             :                                        GQuark                 domain,
     636                 :             :                                        gint                   code,
     637                 :             :                                        const gchar           *format,
     638                 :             :                                        ...)
     639                 :             : {
     640                 :             :   va_list var_args;
     641                 :             : 
     642                 :          23 :   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
     643                 :          23 :   g_return_if_fail (format != NULL);
     644                 :             : 
     645                 :          23 :   va_start (var_args, format);
     646                 :          23 :   g_dbus_method_invocation_return_error_valist (invocation,
     647                 :             :                                                 domain,
     648                 :             :                                                 code,
     649                 :             :                                                 format,
     650                 :             :                                                 var_args);
     651                 :          23 :   va_end (var_args);
     652                 :             : }
     653                 :             : 
     654                 :             : /**
     655                 :             :  * g_dbus_method_invocation_return_error_valist:
     656                 :             :  * @invocation: (transfer full): A #GDBusMethodInvocation.
     657                 :             :  * @domain: A #GQuark for the #GError error domain.
     658                 :             :  * @code: The error code.
     659                 :             :  * @format: printf()-style format.
     660                 :             :  * @var_args: #va_list of parameters for @format.
     661                 :             :  *
     662                 :             :  * Like g_dbus_method_invocation_return_error() but intended for
     663                 :             :  * language bindings.
     664                 :             :  *
     665                 :             :  * This method will take ownership of @invocation. See
     666                 :             :  * #GDBusInterfaceVTable for more information about the ownership of
     667                 :             :  * @invocation.
     668                 :             :  *
     669                 :             :  * Since: 2.26
     670                 :             :  */
     671                 :             : void
     672                 :          23 : g_dbus_method_invocation_return_error_valist (GDBusMethodInvocation *invocation,
     673                 :             :                                               GQuark                 domain,
     674                 :             :                                               gint                   code,
     675                 :             :                                               const gchar           *format,
     676                 :             :                                               va_list                var_args)
     677                 :             : {
     678                 :             :   gchar *literal_message;
     679                 :             : 
     680                 :          23 :   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
     681                 :          23 :   g_return_if_fail (format != NULL);
     682                 :             : 
     683                 :          23 :   literal_message = g_strdup_vprintf (format, var_args);
     684                 :          23 :   g_dbus_method_invocation_return_error_literal (invocation,
     685                 :             :                                                  domain,
     686                 :             :                                                  code,
     687                 :             :                                                  literal_message);
     688                 :          23 :   g_free (literal_message);
     689                 :             : }
     690                 :             : 
     691                 :             : /**
     692                 :             :  * g_dbus_method_invocation_return_error_literal:
     693                 :             :  * @invocation: (transfer full): A #GDBusMethodInvocation.
     694                 :             :  * @domain: A #GQuark for the #GError error domain.
     695                 :             :  * @code: The error code.
     696                 :             :  * @message: The error message.
     697                 :             :  *
     698                 :             :  * Like g_dbus_method_invocation_return_error() but without printf()-style formatting.
     699                 :             :  *
     700                 :             :  * This method will take ownership of @invocation. See
     701                 :             :  * #GDBusInterfaceVTable for more information about the ownership of
     702                 :             :  * @invocation.
     703                 :             :  *
     704                 :             :  * Since: 2.26
     705                 :             :  */
     706                 :             : void
     707                 :          23 : g_dbus_method_invocation_return_error_literal (GDBusMethodInvocation *invocation,
     708                 :             :                                                GQuark                 domain,
     709                 :             :                                                gint                   code,
     710                 :             :                                                const gchar           *message)
     711                 :             : {
     712                 :             :   GError *error;
     713                 :             : 
     714                 :          23 :   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
     715                 :          23 :   g_return_if_fail (message != NULL);
     716                 :             : 
     717                 :          23 :   error = g_error_new_literal (domain, code, message);
     718                 :          23 :   g_dbus_method_invocation_return_gerror (invocation, error);
     719                 :          23 :   g_error_free (error);
     720                 :             : }
     721                 :             : 
     722                 :             : /**
     723                 :             :  * g_dbus_method_invocation_return_gerror:
     724                 :             :  * @invocation: (transfer full): A #GDBusMethodInvocation.
     725                 :             :  * @error: A #GError.
     726                 :             :  *
     727                 :             :  * Like g_dbus_method_invocation_return_error() but takes a #GError
     728                 :             :  * instead of the error domain, error code and message.
     729                 :             :  *
     730                 :             :  * This method will take ownership of @invocation. See
     731                 :             :  * #GDBusInterfaceVTable for more information about the ownership of
     732                 :             :  * @invocation.
     733                 :             :  *
     734                 :             :  * Since: 2.26
     735                 :             :  */
     736                 :             : void
     737                 :          25 : g_dbus_method_invocation_return_gerror (GDBusMethodInvocation *invocation,
     738                 :             :                                         const GError          *error)
     739                 :             : {
     740                 :             :   gchar *dbus_error_name;
     741                 :             : 
     742                 :          25 :   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
     743                 :          25 :   g_return_if_fail (error != NULL);
     744                 :             : 
     745                 :          25 :   dbus_error_name = g_dbus_error_encode_gerror (error);
     746                 :             : 
     747                 :          25 :   g_dbus_method_invocation_return_dbus_error (invocation,
     748                 :             :                                               dbus_error_name,
     749                 :          25 :                                               error->message);
     750                 :          25 :   g_free (dbus_error_name);
     751                 :             : }
     752                 :             : 
     753                 :             : /**
     754                 :             :  * g_dbus_method_invocation_take_error: (skip)
     755                 :             :  * @invocation: (transfer full): A #GDBusMethodInvocation.
     756                 :             :  * @error: (transfer full): A #GError.
     757                 :             :  *
     758                 :             :  * Like g_dbus_method_invocation_return_gerror() but takes ownership
     759                 :             :  * of @error so the caller does not need to free it.
     760                 :             :  *
     761                 :             :  * This method will take ownership of @invocation. See
     762                 :             :  * #GDBusInterfaceVTable for more information about the ownership of
     763                 :             :  * @invocation.
     764                 :             :  *
     765                 :             :  * Since: 2.30
     766                 :             :  */
     767                 :             : void
     768                 :           2 : g_dbus_method_invocation_take_error (GDBusMethodInvocation *invocation,
     769                 :             :                                      GError                *error)
     770                 :             : {
     771                 :           2 :   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
     772                 :           2 :   g_return_if_fail (error != NULL);
     773                 :           2 :   g_dbus_method_invocation_return_gerror (invocation, error);
     774                 :           2 :   g_error_free (error);
     775                 :             : }
     776                 :             : 
     777                 :             : /**
     778                 :             :  * g_dbus_method_invocation_return_dbus_error:
     779                 :             :  * @invocation: (transfer full): A #GDBusMethodInvocation.
     780                 :             :  * @error_name: A valid D-Bus error name.
     781                 :             :  * @error_message: A valid D-Bus error message.
     782                 :             :  *
     783                 :             :  * Finishes handling a D-Bus method call by returning an error.
     784                 :             :  *
     785                 :             :  * This method will take ownership of @invocation. See
     786                 :             :  * #GDBusInterfaceVTable for more information about the ownership of
     787                 :             :  * @invocation.
     788                 :             :  *
     789                 :             :  * Since: 2.26
     790                 :             :  */
     791                 :             : void
     792                 :          31 : g_dbus_method_invocation_return_dbus_error (GDBusMethodInvocation *invocation,
     793                 :             :                                             const gchar           *error_name,
     794                 :             :                                             const gchar           *error_message)
     795                 :             : {
     796                 :             :   GDBusMessage *reply;
     797                 :             : 
     798                 :          31 :   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
     799                 :          31 :   g_return_if_fail (error_name != NULL && g_dbus_is_name (error_name));
     800                 :          31 :   g_return_if_fail (error_message != NULL);
     801                 :             : 
     802                 :          31 :   if (g_dbus_message_get_flags (invocation->message) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED)
     803                 :           1 :     goto out;
     804                 :             : 
     805                 :          30 :   if (G_UNLIKELY (_g_dbus_debug_return ()))
     806                 :             :     {
     807                 :           0 :       _g_dbus_debug_print_lock ();
     808                 :           0 :       g_print ("========================================================================\n"
     809                 :             :                "GDBus-debug:Return:\n"
     810                 :             :                " >>>> METHOD ERROR %s\n"
     811                 :             :                "      message '%s'\n"
     812                 :             :                "      in response to %s.%s()\n"
     813                 :             :                "      on object %s\n"
     814                 :             :                "      to name %s\n"
     815                 :             :                "      reply-serial %d\n",
     816                 :             :                error_name,
     817                 :             :                error_message,
     818                 :             :                invocation->interface_name, invocation->method_name,
     819                 :             :                invocation->object_path,
     820                 :             :                invocation->sender,
     821                 :             :                g_dbus_message_get_serial (invocation->message));
     822                 :           0 :       _g_dbus_debug_print_unlock ();
     823                 :             :     }
     824                 :             : 
     825                 :          30 :   reply = g_dbus_message_new_method_error_literal (invocation->message,
     826                 :             :                                                    error_name,
     827                 :             :                                                    error_message);
     828                 :          30 :   g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL);
     829                 :          30 :   g_object_unref (reply);
     830                 :             : 
     831                 :          31 : out:
     832                 :          31 :   g_object_unref (invocation);
     833                 :             : }
        

Generated by: LCOV version 2.0-1