]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
D-Bus: Add support for sending file descriptors with GDBus
authorJürg Billeter <j@bitron.ch>
Mon, 18 Oct 2010 16:37:52 +0000 (18:37 +0200)
committerJürg Billeter <j@bitron.ch>
Sat, 23 Oct 2010 16:11:47 +0000 (18:11 +0200)
codegen/valagdbusclientmodule.vala
codegen/valagdbusmodule.vala
codegen/valagdbusservermodule.vala

index 069b4e42b8d84ed0cd029b1f83ee6ffae8147b4e..44670df3886314547d9ba4eb49c37d13c6bbd862 100644 (file)
@@ -415,6 +415,8 @@ public class Vala.GDBusClientModule : GDBusModule {
        }
 
        void generate_marshalling (Method m, CallType call_type, string? iface_name, string? method_name) {
+               cfile.add_include ("gio/gunixfdlist.h");
+
                var connection = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_get_connection"));
                connection.add_argument (new CCodeIdentifier ("self"));
 
@@ -454,13 +456,17 @@ public class Vala.GDBusClientModule : GDBusModule {
                        builder_init.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
                        ccode.add_expression (builder_init);
 
+                       ccode.add_declaration ("GUnixFDList", new CCodeVariableDeclarator ("*_fd_list"));
+                       ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_fd_list"), new CCodeFunctionCall (new CCodeIdentifier ("g_unix_fd_list_new"))));
+
                        foreach (FormalParameter param in m.get_parameters ()) {
                                if (param.direction == ParameterDirection.IN) {
                                        CCodeExpression expr = new CCodeIdentifier (param.name);
                                        if (param.variable_type.is_real_struct_type ()) {
                                                expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, expr);
                                        }
-                                       write_expression (param.variable_type, new CCodeIdentifier ("_arguments_builder"), expr, param);
+
+                                       send_dbus_value (param.variable_type, new CCodeIdentifier ("_arguments_builder"), expr, param);
                                }
                        }
 
@@ -473,6 +479,15 @@ public class Vala.GDBusClientModule : GDBusModule {
                        set_body.add_argument (new CCodeIdentifier ("_arguments"));
                        ccode.add_expression (set_body);
 
+                       ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_set_unix_fd_list"));
+                       ccall.add_argument (new CCodeIdentifier ("_message"));
+                       ccall.add_argument (new CCodeIdentifier ("_fd_list"));
+                       ccode.add_expression (ccall);
+
+                       ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
+                       ccall.add_argument (new CCodeIdentifier ("_fd_list"));
+                       ccode.add_expression (ccall);
+
                        // send D-Bus message
 
                        if (call_type == CallType.SYNC) {
index 94bf9283d3fa869a5394faf8aed292684545823a..11b7f154f793880fd837d3ced2ccca3f28b72b9e 100644 (file)
@@ -110,4 +110,44 @@ public class Vala.GDBusModule : GVariantModule {
                cquark_fun.block = cquark_block;
                cfile.add_function (cquark_fun);
        }
+
+       CCodeExpression? get_file_descriptor (DataType type, CCodeExpression expr) {
+               if (type is ObjectType) {
+                       if (type.data_type.get_full_name () == "GLib.UnixInputStream") {
+                               var result = new CCodeFunctionCall (new CCodeIdentifier ("g_unix_input_stream_get_fd"));
+                               result.add_argument (expr);
+                               return result;
+                       } else if (type.data_type.get_full_name () == "GLib.UnixOutputStream") {
+                               var result = new CCodeFunctionCall (new CCodeIdentifier ("g_unix_output_stream_get_fd"));
+                               result.add_argument (expr);
+                               return result;
+                       } else if (type.data_type.get_full_name () == "GLib.Socket") {
+                               var result = new CCodeFunctionCall (new CCodeIdentifier ("g_socket_get_fd"));
+                               result.add_argument (expr);
+                               return result;
+                       }
+               }
+
+               return null;
+       }
+
+       public void send_dbus_value (DataType type, CCodeExpression builder_expr, CCodeExpression expr, Symbol? sym) {
+               var fd = get_file_descriptor (type, expr);
+               if (fd != null) {
+                       // add file descriptor to the file descriptor list
+                       var fd_append = new CCodeFunctionCall (new CCodeIdentifier ("g_unix_fd_list_append"));
+                       fd_append.add_argument (new CCodeIdentifier ("_fd_list"));
+                       fd_append.add_argument (fd);
+                       fd_append.add_argument (new CCodeConstant ("NULL"));
+
+                       // add index to file descriptor to gvariant
+                       var builder_add = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_add"));
+                       builder_add.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, builder_expr));
+                       builder_add.add_argument (new CCodeConstant ("\"h\""));
+                       builder_add.add_argument (fd_append);
+                       ccode.add_expression (builder_add);
+               } else {
+                       write_expression (type, builder_expr, expr, sym);
+               }
+       }
 }
index 754204d53f4f6ed95208e9874bf3a5c7effa65f4..fff2f260c1248e77994d65a7036b4a9c86a9cbb6 100644 (file)
@@ -74,6 +74,8 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 
                push_function (function);
 
+               cfile.add_include ("gio/gunixfdlist.h");
+
                if (ready) {
                        ccode.add_declaration ("GDBusMethodInvocation *", new CCodeVariableDeclarator ("invocation", new CCodeIdentifier ("_user_data_")));
                }
@@ -229,6 +231,9 @@ public class Vala.GDBusServerModule : GDBusClientModule {
                        builder_init.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
                        ccode.add_expression (builder_init);
 
+                       ccode.add_declaration ("GUnixFDList", new CCodeVariableDeclarator ("*_fd_list"));
+                       ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_fd_list"), new CCodeFunctionCall (new CCodeIdentifier ("g_unix_fd_list_new"))));
+
                        foreach (FormalParameter param in m.get_parameters ()) {
                                if (param.direction != ParameterDirection.OUT) {
                                        continue;
@@ -248,14 +253,14 @@ public class Vala.GDBusServerModule : GDBusClientModule {
                                        }
                                }
 
-                               write_expression (param.variable_type, new CCodeIdentifier ("_reply_builder"), new CCodeIdentifier (param.name), param);
+                               send_dbus_value (param.variable_type, new CCodeIdentifier ("_reply_builder"), new CCodeIdentifier (param.name), param);
                        }
 
                        if (!(m.return_type is VoidType)) {
                                if (m.return_type.is_real_non_null_struct_type ()) {
                                        ccode.add_declaration (m.return_type.get_cname (), new CCodeVariableDeclarator.zero ("result", default_value_for_type (m.return_type, true)));
 
-                                       write_expression (m.return_type, new CCodeIdentifier ("_reply_builder"), new CCodeIdentifier ("result"), m);
+                                       send_dbus_value (m.return_type, new CCodeIdentifier ("_reply_builder"), new CCodeIdentifier ("result"), m);
 
                                        if (requires_destroy (m.return_type)) {
                                                // keep local alive (symbol_reference is weak)
@@ -280,7 +285,7 @@ public class Vala.GDBusServerModule : GDBusClientModule {
                                                }
                                        }
 
-                                       write_expression (m.return_type, new CCodeIdentifier ("_reply_builder"), new CCodeIdentifier ("result"), m);
+                                       send_dbus_value (m.return_type, new CCodeIdentifier ("_reply_builder"), new CCodeIdentifier ("result"), m);
 
                                        if (requires_destroy (m.return_type)) {
                                                // keep local alive (symbol_reference is weak)
@@ -304,6 +309,15 @@ public class Vala.GDBusServerModule : GDBusClientModule {
                        set_body.add_argument (new CCodeIdentifier ("_reply_message"));
                        set_body.add_argument (new CCodeIdentifier ("_reply"));
                        ccode.add_expression (set_body);
+
+                       ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_set_unix_fd_list"));
+                       ccall.add_argument (new CCodeIdentifier ("_reply_message"));
+                       ccall.add_argument (new CCodeIdentifier ("_fd_list"));
+                       ccode.add_expression (ccall);
+
+                       ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
+                       ccall.add_argument (new CCodeIdentifier ("_fd_list"));
+                       ccode.add_expression (ccall);
                } else {
                        ccode.add_expression (ccall);
                }