5
5
from .exitable import ExitableWithAliases
6
6
from functools import partial
7
7
from .method_call_context import MethodCallContext
8
+ from . import unixfd
8
9
import logging
9
10
10
11
try :
@@ -18,10 +19,12 @@ class ObjectWrapper(ExitableWithAliases("unwrap")):
18
19
def __init__ (self , object , interfaces ):
19
20
self .object = object
20
21
22
+ self .inargs = {}
21
23
self .outargs = {}
22
24
for iface in interfaces :
23
25
for method in iface .methods :
24
26
self .outargs [iface .name + "." + method .name ] = [arg .signature for arg in method .out_args ]
27
+ self .inargs [iface .name + "." + method .name ] = [arg .signature for arg in method .in_args ]
25
28
26
29
self .readable_properties = {}
27
30
self .writable_properties = {}
@@ -54,19 +57,23 @@ def onPropertiesChanged(iface, changed, invalidated):
54
57
def call_method (self , connection , sender , object_path , interface_name , method_name , parameters , invocation ):
55
58
try :
56
59
try :
60
+ inargs = self .inargs [interface_name + "." + method_name ]
57
61
outargs = self .outargs [interface_name + "." + method_name ]
58
62
method = getattr (self .object , method_name )
59
63
except KeyError :
60
64
if interface_name == "org.freedesktop.DBus.Properties" :
61
65
if method_name == "Get" :
62
66
method = self .Get
63
67
outargs = ["v" ]
68
+ inargs = ["ss" ]
64
69
elif method_name == "GetAll" :
65
70
method = self .GetAll
66
71
outargs = ["a{sv}" ]
72
+ inargs = ["s" ]
67
73
elif method_name == "Set" :
68
74
method = self .Set
69
75
outargs = []
76
+ inargs = ["ssv" ]
70
77
else :
71
78
raise
72
79
else :
@@ -78,14 +85,23 @@ def call_method(self, connection, sender, object_path, interface_name, method_na
78
85
if "dbus_context" in sig .parameters and sig .parameters ["dbus_context" ].kind in (Parameter .POSITIONAL_OR_KEYWORD , Parameter .KEYWORD_ONLY ):
79
86
kwargs ["dbus_context" ] = MethodCallContext (invocation )
80
87
88
+ if unixfd .is_supported (connection ):
89
+ parameters = unixfd .extract (
90
+ parameters ,
91
+ inargs ,
92
+ invocation .get_message ().get_unix_fd_list ())
93
+
81
94
result = method (* parameters , ** kwargs )
82
95
83
96
if len (outargs ) == 0 :
84
97
invocation .return_value (None )
85
- elif len (outargs ) == 1 :
86
- invocation .return_value (GLib .Variant ("(" + "" .join (outargs ) + ")" , (result ,)))
87
98
else :
88
- invocation .return_value (GLib .Variant ("(" + "" .join (outargs ) + ")" , result ))
99
+ if len (outargs ) == 1 :
100
+ result = (result , )
101
+ if unixfd .is_supported (connection ):
102
+ invocation .return_value_with_unix_fd_list (GLib .Variant ("(" + "" .join (outargs ) + ")" , result ), unixfd .make_fd_list (result , outargs , steal = True ))
103
+ else :
104
+ invocation .return_value (GLib .Variant ("(" + "" .join (outargs ) + ")" , result ))
89
105
90
106
except Exception as e :
91
107
logger = logging .getLogger (__name__ )
@@ -151,6 +167,5 @@ def register_object(self, path, object, node_info):
151
167
152
168
node_info = [Gio .DBusNodeInfo .new_for_xml (ni ) for ni in node_info ]
153
169
interfaces = sum ((ni .interfaces for ni in node_info ), [])
154
-
155
170
wrapper = ObjectWrapper (object , interfaces )
156
171
return ObjectRegistration (self , path , interfaces , wrapper , own_wrapper = True )
0 commit comments