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