[glib: 1/2] gdbus: Add FD support for gdbus call




commit a879c46a39e5f1dc94fa7083e75f727992744cce
Author: Norbert Pocs <npocs redhat com>
Date:   Fri Nov 6 17:19:27 2020 +0000

    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

 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,)
 </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>
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;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]