Coverage Report

Created: 2025-11-16 07:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/glib-2.80.0/gio/gdbusmethodinvocation.c
Line
Count
Source
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
0
G_DEFINE_TYPE (GDBusMethodInvocation, g_dbus_method_invocation, G_TYPE_OBJECT)
91
0
92
0
static void
93
0
g_dbus_method_invocation_finalize (GObject *object)
94
0
{
95
0
  GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (object);
96
97
0
  g_free (invocation->sender);
98
0
  g_free (invocation->object_path);
99
0
  g_free (invocation->interface_name);
100
0
  g_free (invocation->method_name);
101
0
  if (invocation->method_info)
102
0
      g_dbus_method_info_unref (invocation->method_info);
103
0
  if (invocation->property_info)
104
0
      g_dbus_property_info_unref (invocation->property_info);
105
0
  g_object_unref (invocation->connection);
106
0
  g_object_unref (invocation->message);
107
0
  g_variant_unref (invocation->parameters);
108
109
0
  G_OBJECT_CLASS (g_dbus_method_invocation_parent_class)->finalize (object);
110
0
}
111
112
static void
113
g_dbus_method_invocation_class_init (GDBusMethodInvocationClass *klass)
114
0
{
115
0
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
116
117
0
  gobject_class->finalize = g_dbus_method_invocation_finalize;
118
0
}
119
120
static void
121
g_dbus_method_invocation_init (GDBusMethodInvocation *invocation)
122
0
{
123
0
}
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
g_dbus_method_invocation_get_sender (GDBusMethodInvocation *invocation)
137
0
{
138
0
  g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
139
0
  return invocation->sender;
140
0
}
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
g_dbus_method_invocation_get_object_path (GDBusMethodInvocation *invocation)
154
0
{
155
0
  g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
156
0
  return invocation->object_path;
157
0
}
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
g_dbus_method_invocation_get_interface_name (GDBusMethodInvocation *invocation)
176
0
{
177
0
  g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
178
0
  return invocation->interface_name;
179
0
}
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
g_dbus_method_invocation_get_method_info (GDBusMethodInvocation *invocation)
198
0
{
199
0
  g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
200
0
  return invocation->method_info;
201
0
}
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
g_dbus_method_invocation_get_property_info (GDBusMethodInvocation *invocation)
225
0
{
226
0
  g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
227
0
  return invocation->property_info;
228
0
}
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
g_dbus_method_invocation_get_method_name (GDBusMethodInvocation *invocation)
242
0
{
243
0
  g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
244
0
  return invocation->method_name;
245
0
}
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
g_dbus_method_invocation_get_connection (GDBusMethodInvocation *invocation)
259
0
{
260
0
  g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
261
0
  return invocation->connection;
262
0
}
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
g_dbus_method_invocation_get_message (GDBusMethodInvocation *invocation)
283
0
{
284
0
  g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
285
0
  return invocation->message;
286
0
}
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
g_dbus_method_invocation_get_parameters (GDBusMethodInvocation *invocation)
301
0
{
302
0
  g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
303
0
  return invocation->parameters;
304
0
}
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
g_dbus_method_invocation_get_user_data (GDBusMethodInvocation *invocation)
318
0
{
319
0
  g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
320
0
  return invocation->user_data;
321
0
}
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
_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
0
{
354
0
  GDBusMethodInvocation *invocation;
355
356
0
  g_return_val_if_fail (sender == NULL || g_dbus_is_name (sender), NULL);
357
0
  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
358
0
  g_return_val_if_fail (interface_name == NULL || g_dbus_is_interface_name (interface_name), NULL);
359
0
  g_return_val_if_fail (g_dbus_is_member_name (method_name), NULL);
360
0
  g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
361
0
  g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
362
0
  g_return_val_if_fail (g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE), NULL);
363
364
0
  invocation = G_DBUS_METHOD_INVOCATION (g_object_new (G_TYPE_DBUS_METHOD_INVOCATION, NULL));
365
0
  invocation->sender = g_strdup (sender);
366
0
  invocation->object_path = g_strdup (object_path);
367
0
  invocation->interface_name = g_strdup (interface_name);
368
0
  invocation->method_name = g_strdup (method_name);
369
0
  if (method_info)
370
0
    invocation->method_info = g_dbus_method_info_ref ((GDBusMethodInfo *)method_info);
371
0
  if (property_info)
372
0
    invocation->property_info = g_dbus_property_info_ref ((GDBusPropertyInfo *)property_info);
373
0
  invocation->connection = g_object_ref (connection);
374
0
  invocation->message = g_object_ref (message);
375
0
  invocation->parameters = g_variant_ref (parameters);
376
0
  invocation->user_data = user_data;
377
378
0
  return invocation;
379
0
}
380
381
/* ---------------------------------------------------------------------------------------------------- */
382
383
static void
384
g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocation,
385
                                                GVariant              *parameters,
386
                                                GUnixFDList           *fd_list)
387
0
{
388
0
  GDBusMessage *reply;
389
0
  GError *error;
390
391
0
  g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
392
0
  g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));
393
394
0
  if (g_dbus_message_get_flags (invocation->message) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED)
395
0
    goto out;
396
397
0
  if (parameters == NULL)
398
0
    parameters = g_variant_new_tuple (NULL, 0);
399
400
  /* if we have introspection data, check that the signature of @parameters is correct */
401
0
  if (invocation->method_info != NULL)
402
0
    {
403
0
      GVariantType *type;
404
405
0
      type = _g_dbus_compute_complete_signature (invocation->method_info->out_args);
406
407
0
      if (!g_variant_is_of_type (parameters, type))
408
0
        {
409
0
          gchar *type_string = g_variant_type_dup_string (type);
410
411
0
          g_warning ("Type of return value is incorrect: expected '%s', got '%s'",
412
0
         type_string, g_variant_get_type_string (parameters));
413
0
          g_variant_type_free (type);
414
0
          g_free (type_string);
415
0
          goto out;
416
0
        }
417
0
      g_variant_type_free (type);
418
0
    }
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
0
  if (invocation->property_info != NULL)
427
0
    {
428
0
      if (g_str_equal (invocation->method_name, "Get"))
429
0
        {
430
0
          GVariant *nested;
431
432
0
          if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(v)")))
433
0
            {
434
0
              g_warning ("Type of return value for property 'Get' call should be '(v)' but got '%s'",
435
0
                         g_variant_get_type_string (parameters));
436
0
              goto out;
437
0
            }
438
439
          /* Go deeper and make sure that the value inside of the
440
           * variant matches the property type.
441
           */
442
0
          g_variant_get (parameters, "(v)", &nested);
443
0
          if (!g_str_equal (g_variant_get_type_string (nested), invocation->property_info->signature))
444
0
            {
445
0
              g_warning ("Value returned from property 'Get' call for '%s' should be '%s' but is '%s'",
446
0
                         invocation->property_info->name, invocation->property_info->signature,
447
0
                         g_variant_get_type_string (nested));
448
0
              g_variant_unref (nested);
449
0
              goto out;
450
0
            }
451
0
          g_variant_unref (nested);
452
0
        }
453
454
0
      else if (g_str_equal (invocation->method_name, "Set"))
455
0
        {
456
0
          if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE_UNIT))
457
0
            {
458
0
              g_warning ("Type of return value for property 'Set' call should be '()' but got '%s'",
459
0
                         g_variant_get_type_string (parameters));
460
0
              goto out;
461
0
            }
462
0
        }
463
464
0
      else
465
0
        g_assert_not_reached ();
466
0
    }
467
0
  else if (g_str_equal (invocation->interface_name, "org.freedesktop.DBus.Properties") &&
468
0
           g_str_equal (invocation->method_name, "GetAll"))
469
0
    {
470
0
      if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a{sv})")))
471
0
        {
472
0
          g_warning ("Type of return value for property 'GetAll' call should be '(a{sv})' but got '%s'",
473
0
                     g_variant_get_type_string (parameters));
474
0
          goto out;
475
0
        }
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
0
    }
482
483
0
  if (G_UNLIKELY (_g_dbus_debug_return ()))
484
0
    {
485
0
      _g_dbus_debug_print_lock ();
486
0
      g_print ("========================================================================\n"
487
0
               "GDBus-debug:Return:\n"
488
0
               " >>>> METHOD RETURN\n"
489
0
               "      in response to %s.%s()\n"
490
0
               "      on object %s\n"
491
0
               "      to name %s\n"
492
0
               "      reply-serial %d\n",
493
0
               invocation->interface_name, invocation->method_name,
494
0
               invocation->object_path,
495
0
               invocation->sender,
496
0
               g_dbus_message_get_serial (invocation->message));
497
0
      _g_dbus_debug_print_unlock ();
498
0
    }
499
500
0
  reply = g_dbus_message_new_method_reply (invocation->message);
501
0
  g_dbus_message_set_body (reply, g_steal_pointer (&parameters));
502
503
0
#ifdef G_OS_UNIX
504
0
  if (fd_list != NULL)
505
0
    g_dbus_message_set_unix_fd_list (reply, fd_list);
506
0
#endif
507
508
0
  error = NULL;
509
0
  if (!g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error))
510
0
    {
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
0
    }
515
0
  g_object_unref (reply);
516
517
0
 out:
518
0
  if (parameters != NULL)
519
0
    {
520
0
      g_variant_ref_sink (parameters);
521
0
      g_variant_unref (parameters);
522
0
    }
523
524
0
  g_object_unref (invocation);
525
0
}
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
g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation,
569
                                       GVariant              *parameters)
570
0
{
571
0
  g_dbus_method_invocation_return_value_internal (invocation, parameters, NULL);
572
0
}
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
g_dbus_method_invocation_return_value_with_unix_fd_list (GDBusMethodInvocation *invocation,
593
                                                         GVariant              *parameters,
594
                                                         GUnixFDList           *fd_list)
595
0
{
596
0
  g_dbus_method_invocation_return_value_internal (invocation, parameters, fd_list);
597
0
}
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
g_dbus_method_invocation_return_error (GDBusMethodInvocation *invocation,
635
                                       GQuark                 domain,
636
                                       gint                   code,
637
                                       const gchar           *format,
638
                                       ...)
639
0
{
640
0
  va_list var_args;
641
642
0
  g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
643
0
  g_return_if_fail (format != NULL);
644
645
0
  va_start (var_args, format);
646
0
  g_dbus_method_invocation_return_error_valist (invocation,
647
0
                                                domain,
648
0
                                                code,
649
0
                                                format,
650
0
                                                var_args);
651
0
  va_end (var_args);
652
0
}
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
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
0
{
678
0
  gchar *literal_message;
679
680
0
  g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
681
0
  g_return_if_fail (format != NULL);
682
683
0
  literal_message = g_strdup_vprintf (format, var_args);
684
0
  g_dbus_method_invocation_return_error_literal (invocation,
685
0
                                                 domain,
686
0
                                                 code,
687
0
                                                 literal_message);
688
0
  g_free (literal_message);
689
0
}
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
g_dbus_method_invocation_return_error_literal (GDBusMethodInvocation *invocation,
708
                                               GQuark                 domain,
709
                                               gint                   code,
710
                                               const gchar           *message)
711
0
{
712
0
  GError *error;
713
714
0
  g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
715
0
  g_return_if_fail (message != NULL);
716
717
0
  error = g_error_new_literal (domain, code, message);
718
0
  g_dbus_method_invocation_return_gerror (invocation, error);
719
0
  g_error_free (error);
720
0
}
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
g_dbus_method_invocation_return_gerror (GDBusMethodInvocation *invocation,
738
                                        const GError          *error)
739
0
{
740
0
  gchar *dbus_error_name;
741
742
0
  g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
743
0
  g_return_if_fail (error != NULL);
744
745
0
  dbus_error_name = g_dbus_error_encode_gerror (error);
746
747
0
  g_dbus_method_invocation_return_dbus_error (invocation,
748
0
                                              dbus_error_name,
749
0
                                              error->message);
750
0
  g_free (dbus_error_name);
751
0
}
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
g_dbus_method_invocation_take_error (GDBusMethodInvocation *invocation,
769
                                     GError                *error)
770
0
{
771
0
  g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
772
0
  g_return_if_fail (error != NULL);
773
0
  g_dbus_method_invocation_return_gerror (invocation, error);
774
0
  g_error_free (error);
775
0
}
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
g_dbus_method_invocation_return_dbus_error (GDBusMethodInvocation *invocation,
793
                                            const gchar           *error_name,
794
                                            const gchar           *error_message)
795
0
{
796
0
  GDBusMessage *reply;
797
798
0
  g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
799
0
  g_return_if_fail (error_name != NULL && g_dbus_is_name (error_name));
800
0
  g_return_if_fail (error_message != NULL);
801
802
0
  if (g_dbus_message_get_flags (invocation->message) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED)
803
0
    goto out;
804
805
0
  if (G_UNLIKELY (_g_dbus_debug_return ()))
806
0
    {
807
0
      _g_dbus_debug_print_lock ();
808
0
      g_print ("========================================================================\n"
809
0
               "GDBus-debug:Return:\n"
810
0
               " >>>> METHOD ERROR %s\n"
811
0
               "      message '%s'\n"
812
0
               "      in response to %s.%s()\n"
813
0
               "      on object %s\n"
814
0
               "      to name %s\n"
815
0
               "      reply-serial %d\n",
816
0
               error_name,
817
0
               error_message,
818
0
               invocation->interface_name, invocation->method_name,
819
0
               invocation->object_path,
820
0
               invocation->sender,
821
0
               g_dbus_message_get_serial (invocation->message));
822
0
      _g_dbus_debug_print_unlock ();
823
0
    }
824
825
0
  reply = g_dbus_message_new_method_error_literal (invocation->message,
826
0
                                                   error_name,
827
0
                                                   error_message);
828
0
  g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL);
829
0
  g_object_unref (reply);
830
831
0
out:
832
0
  g_object_unref (invocation);
833
0
}