}
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"));
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);
}
}
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) {
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);
+ }
+ }
}
push_function (function);
+ cfile.add_include ("gio/gunixfdlist.h");
+
if (ready) {
ccode.add_declaration ("GDBusMethodInvocation *", new CCodeVariableDeclarator ("invocation", new CCodeIdentifier ("_user_data_")));
}
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;
}
}
- 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)
}
}
- 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)
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);
}