From a879c46a39e5f1dc94fa7083e75f727992744cce Mon Sep 17 00:00:00 2001 From: Norbert Pocs Date: Fri, 6 Nov 2020 17:19:27 +0000 Subject: [PATCH] gdbus: Add FD support for gdbus call Gdbus call could not take file handle (parameter 'h') as a parameter. Original patch from Tim Waugh . Fixes: #961 --- docs/reference/gio/gdbus.xml | 12 +++++++ gio/gdbus-tool.c | 67 ++++++++++++++++++++++++++++++------ 2 files changed, 69 insertions(+), 10 deletions(-) diff --git a/docs/reference/gio/gdbus.xml b/docs/reference/gio/gdbus.xml index 0e6c14db1..77fdfebed 100644 --- a/docs/reference/gio/gdbus.xml +++ b/docs/reference/gio/gdbus.xml @@ -321,6 +321,18 @@ $ gdbus call --session \ 5000 (uint32 12,) + + Call a method with file handle argument: + + +$ gdbus call --session \ + --dest org.example.foo \ + --object-path /org/example/foo \ + --method SendFDs \ + 1 \ + 10 \ + 10<file.foo + Monitoring all objects on a service: diff --git a/gio/gdbus-tool.c b/gio/gdbus-tool.c index 863a5e80a..78198df00 100644 --- a/gio/gdbus-tool.c +++ b/gio/gdbus-tool.c @@ -27,6 +27,10 @@ #include +#ifdef G_OS_UNIX +#include +#endif + #include #ifdef G_OS_WIN32 @@ -905,6 +909,10 @@ handle_call (gint *argc, gchar *method_name; GVariant *result; GPtrArray *in_signature_types; +#ifdef G_OS_UNIX + GUnixFDList *fd_list; + guint fd_id; +#endif gboolean complete_names; gboolean complete_paths; gboolean complete_methods; @@ -920,6 +928,9 @@ handle_call (gint *argc, method_name = NULL; result = NULL; in_signature_types = NULL; +#ifdef G_OS_UNIX + fd_list = NULL; +#endif modify_argv0_for_command (argc, argv, "call"); @@ -1164,6 +1175,23 @@ handle_call (gint *argc, } g_free (context); } +#ifdef G_OS_UNIX + if (g_variant_is_of_type (value, G_VARIANT_TYPE_HANDLE)) + { + if (!fd_list) + fd_list = g_unix_fd_list_new (); + if ((fd_id = g_unix_fd_list_append (fd_list, g_variant_get_handle (value), &error)) == -1) + { + g_printerr (_("Error adding handle %d: %s\n"), + g_variant_get_handle (value), error->message); + g_variant_builder_clear (&builder); + g_error_free (error); + goto out; + } + g_variant_unref (value); + value = g_variant_new_handle (fd_id); + } +#endif g_variant_builder_add_value (&builder, value); ++parm; } @@ -1171,17 +1199,33 @@ handle_call (gint *argc, if (parameters != NULL) parameters = g_variant_ref_sink (parameters); +#ifdef G_OS_UNIX + result = g_dbus_connection_call_with_unix_fd_list_sync (c, + opt_call_dest, + opt_call_object_path, + interface_name, + method_name, + parameters, + NULL, + G_DBUS_CALL_FLAGS_NONE, + opt_call_timeout > 0 ? opt_call_timeout * 1000 : opt_call_timeout, + fd_list, + NULL, + NULL, + &error); +#else result = g_dbus_connection_call_sync (c, - opt_call_dest, - opt_call_object_path, - interface_name, - method_name, - parameters, - NULL, - G_DBUS_CALL_FLAGS_NONE, - opt_call_timeout > 0 ? opt_call_timeout * 1000 : opt_call_timeout, - NULL, - &error); + opt_call_dest, + opt_call_object_path, + interface_name, + method_name, + parameters, + NULL, + G_DBUS_CALL_FLAGS_NONE, + opt_call_timeout > 0 ? opt_call_timeout * 1000 : opt_call_timeout, + NULL, + &error); +#endif if (result == NULL) { g_printerr (_("Error: %s\n"), error->message); @@ -1230,6 +1274,9 @@ handle_call (gint *argc, g_free (interface_name); g_free (method_name); g_option_context_free (o); +#ifdef G_OS_UNIX + g_clear_object (&fd_list); +#endif return ret; }