From: Jürg Billeter Date: Mon, 18 Oct 2010 16:37:52 +0000 (+0200) Subject: D-Bus: Add support for sending file descriptors with GDBus X-Git-Tag: 0.11.1~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4584bde2e8c07e823b261a97b5cc3b37260a4bd4;p=thirdparty%2Fvala.git D-Bus: Add support for sending file descriptors with GDBus --- diff --git a/codegen/valagdbusclientmodule.vala b/codegen/valagdbusclientmodule.vala index 069b4e42b..44670df38 100644 --- a/codegen/valagdbusclientmodule.vala +++ b/codegen/valagdbusclientmodule.vala @@ -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) { diff --git a/codegen/valagdbusmodule.vala b/codegen/valagdbusmodule.vala index 94bf9283d..11b7f154f 100644 --- a/codegen/valagdbusmodule.vala +++ b/codegen/valagdbusmodule.vala @@ -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); + } + } } diff --git a/codegen/valagdbusservermodule.vala b/codegen/valagdbusservermodule.vala index 754204d53..fff2f260c 100644 --- a/codegen/valagdbusservermodule.vala +++ b/codegen/valagdbusservermodule.vala @@ -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); }