summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNorbert Pocs <npocs@redhat.com>2020-11-06 17:19:27 +0000
committerPhilip Withnall <philip@tecnocode.co.uk>2020-11-06 17:19:27 +0000
commita879c46a39e5f1dc94fa7083e75f727992744cce (patch)
treeb4fb8edb1fa9bfb034b587b32c02d2e448fb50f0
parent63dfceedd2fe942bf09be808a624e114f9b9e52e (diff)
downloadglib-a879c46a39e5f1dc94fa7083e75f727992744cce.tar.gz
gdbus: Add FD support for gdbus call
Gdbus call could not take file handle (parameter 'h') as a parameter. Original patch from Tim Waugh <twaugh@redhat.com>. Fixes: #961
-rw-r--r--docs/reference/gio/gdbus.xml12
-rw-r--r--gio/gdbus-tool.c67
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
@@ -322,6 +322,18 @@ $ gdbus call --session \
(uint32 12,)
</programlisting>
<para>
+ Call a method with file handle argument:
+</para>
+<programlisting>
+$ gdbus call --session \
+ --dest org.example.foo \
+ --object-path /org/example/foo \
+ --method SendFDs \
+ 1 \
+ 10 \
+ 10&lt;file.foo
+</programlisting>
+<para>
Monitoring all objects on a service:
</para>
<programlisting>
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 <gio/gio.h>
+#ifdef G_OS_UNIX
+#include <gio/gunixfdlist.h>
+#endif
+
#include <gi18n.h>
#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;
}