[vala/gdbus: 6/11] D-Bus: Add support for sending file descriptors with GDBus



commit 14e17ce8381bbc52d1f2830fbba0924273de98ca
Author: Jürg Billeter <j bitron ch>
Date:   Mon Oct 18 18:37:52 2010 +0200

    D-Bus: Add support for sending file descriptors with GDBus

 codegen/valagdbusclientmodule.vala |   17 ++++++++++++++-
 codegen/valagdbusmodule.vala       |   40 ++++++++++++++++++++++++++++++++++++
 codegen/valagdbusservermodule.vala |   20 +++++++++++++++--
 3 files changed, 73 insertions(+), 4 deletions(-)
---
diff --git a/codegen/valagdbusclientmodule.vala b/codegen/valagdbusclientmodule.vala
index 069b4e4..44670df 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 94bf928..11b7f15 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 754204d..fff2f26 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);
 		}



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