ruby-dbus 0.17.0 → 0.18.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/NEWS.md +15 -0
- data/README.md +1 -1
- data/Rakefile +3 -11
- data/VERSION +1 -1
- data/doc/Reference.md +9 -2
- data/examples/doc/_extract_examples +2 -0
- data/examples/gdbus/gdbus +11 -5
- data/examples/no-introspect/nm-test.rb +2 -0
- data/examples/no-introspect/tracker-test.rb +3 -1
- data/examples/rhythmbox/playpause.rb +2 -1
- data/examples/service/call_service.rb +1 -0
- data/examples/service/service_newapi.rb +1 -1
- data/examples/simple/call_introspect.rb +1 -0
- data/examples/simple/get_id.rb +2 -1
- data/examples/simple/properties.rb +2 -0
- data/examples/utils/listnames.rb +1 -0
- data/examples/utils/notify.rb +1 -0
- data/lib/dbus/api_options.rb +9 -0
- data/lib/dbus/auth.rb +12 -7
- data/lib/dbus/bus.rb +114 -70
- data/lib/dbus/bus_name.rb +12 -8
- data/lib/dbus/error.rb +4 -2
- data/lib/dbus/introspect.rb +29 -18
- data/lib/dbus/logger.rb +3 -1
- data/lib/dbus/marshall.rb +118 -86
- data/lib/dbus/matchrule.rb +16 -16
- data/lib/dbus/message.rb +40 -27
- data/lib/dbus/message_queue.rb +10 -5
- data/lib/dbus/object.rb +34 -13
- data/lib/dbus/object_path.rb +9 -5
- data/lib/dbus/proxy_object.rb +18 -4
- data/lib/dbus/proxy_object_factory.rb +11 -7
- data/lib/dbus/proxy_object_interface.rb +26 -22
- data/lib/dbus/type.rb +41 -34
- data/lib/dbus/xml.rb +28 -17
- data/lib/dbus.rb +7 -7
- data/ruby-dbus.gemspec +4 -2
- data/spec/async_spec.rb +2 -0
- data/spec/binding_spec.rb +2 -0
- data/spec/bus_and_xml_backend_spec.rb +2 -0
- data/spec/bus_driver_spec.rb +2 -0
- data/spec/bus_name_spec.rb +3 -1
- data/spec/bus_spec.rb +2 -0
- data/spec/byte_array_spec.rb +2 -0
- data/spec/client_robustness_spec.rb +4 -2
- data/spec/err_msg_spec.rb +2 -0
- data/spec/introspect_xml_parser_spec.rb +2 -0
- data/spec/introspection_spec.rb +2 -0
- data/spec/main_loop_spec.rb +2 -0
- data/spec/node_spec.rb +23 -0
- data/spec/object_path_spec.rb +2 -0
- data/spec/property_spec.rb +11 -2
- data/spec/proxy_object_spec.rb +2 -0
- data/spec/server_robustness_spec.rb +2 -0
- data/spec/server_spec.rb +2 -0
- data/spec/service_newapi.rb +19 -4
- data/spec/session_bus_spec.rb +3 -1
- data/spec/session_bus_spec_manual.rb +2 -0
- data/spec/signal_spec.rb +2 -0
- data/spec/spec_helper.rb +5 -3
- data/spec/thread_safety_spec.rb +2 -0
- data/spec/type_spec.rb +2 -0
- data/spec/value_spec.rb +16 -1
- data/spec/variant_spec.rb +4 -2
- metadata +8 -7
data/lib/dbus/marshall.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# dbus.rb - Module containing the low-level D-Bus implementation
|
2
4
|
#
|
3
5
|
# This file is part of the ruby-dbus project
|
@@ -34,11 +36,12 @@ module DBus
|
|
34
36
|
def initialize(buffer, endianness)
|
35
37
|
@buffy = buffer.dup
|
36
38
|
@endianness = endianness
|
37
|
-
|
39
|
+
case @endianness
|
40
|
+
when BIG_END
|
38
41
|
@uint32 = "N"
|
39
42
|
@uint16 = "n"
|
40
43
|
@double = "G"
|
41
|
-
|
44
|
+
when LIL_END
|
42
45
|
@uint32 = "V"
|
43
46
|
@uint16 = "v"
|
44
47
|
@double = "E"
|
@@ -50,12 +53,14 @@ module DBus
|
|
50
53
|
|
51
54
|
# Unmarshall the buffer for a given _signature_ and length _len_.
|
52
55
|
# Return an array of unmarshalled objects
|
56
|
+
# @param signature [Signature]
|
57
|
+
# @param len [Integer,nil] if given, and there is not enough data
|
58
|
+
# in the buffer, raise {IncompleteBufferException}
|
59
|
+
# @return [Array<::Object>]
|
60
|
+
# @raise IncompleteBufferException
|
53
61
|
def unmarshall(signature, len = nil)
|
54
|
-
if
|
55
|
-
|
56
|
-
raise IncompleteBufferException
|
57
|
-
end
|
58
|
-
end
|
62
|
+
raise IncompleteBufferException if len && @buffy.bytesize < @idx + len
|
63
|
+
|
59
64
|
sigtree = Type::Parser.new(signature).parse
|
60
65
|
ret = []
|
61
66
|
sigtree.each do |elem|
|
@@ -64,18 +69,18 @@ module DBus
|
|
64
69
|
ret
|
65
70
|
end
|
66
71
|
|
67
|
-
# Align the pointer index on a byte index of
|
72
|
+
# Align the pointer index on a byte index of _alignment_, which
|
68
73
|
# must be 1, 2, 4 or 8.
|
69
|
-
def align(
|
70
|
-
case
|
74
|
+
def align(alignment)
|
75
|
+
case alignment
|
71
76
|
when 1
|
72
77
|
nil
|
73
78
|
when 2, 4, 8
|
74
|
-
bits =
|
79
|
+
bits = alignment - 1
|
75
80
|
@idx = @idx + bits & ~bits
|
76
81
|
raise IncompleteBufferException if @idx > @buffy.bytesize
|
77
82
|
else
|
78
|
-
raise "Unsupported alignment #{
|
83
|
+
raise ArgumentError, "Unsupported alignment #{alignment}"
|
79
84
|
end
|
80
85
|
end
|
81
86
|
|
@@ -87,6 +92,7 @@ module DBus
|
|
87
92
|
# Retrieve the next _nbytes_ number of bytes from the buffer.
|
88
93
|
def read(nbytes)
|
89
94
|
raise IncompleteBufferException if @idx + nbytes > @buffy.bytesize
|
95
|
+
|
90
96
|
ret = @buffy.slice(@idx, nbytes)
|
91
97
|
@idx += nbytes
|
92
98
|
ret
|
@@ -96,13 +102,15 @@ module DBus
|
|
96
102
|
# Return the string.
|
97
103
|
def read_string
|
98
104
|
align(4)
|
99
|
-
str_sz = read(4).
|
105
|
+
str_sz = read(4).unpack1(@uint32)
|
100
106
|
ret = @buffy.slice(@idx, str_sz)
|
101
107
|
raise IncompleteBufferException if @idx + str_sz + 1 > @buffy.bytesize
|
108
|
+
|
102
109
|
@idx += str_sz
|
103
110
|
if @buffy[@idx].ord != 0
|
104
111
|
raise InvalidPacketException, "String is not nul-terminated"
|
105
112
|
end
|
113
|
+
|
106
114
|
@idx += 1
|
107
115
|
# no exception, see check above
|
108
116
|
ret
|
@@ -111,13 +119,15 @@ module DBus
|
|
111
119
|
# Read the signature length and signature itself from the buffer.
|
112
120
|
# Return the signature.
|
113
121
|
def read_signature
|
114
|
-
str_sz = read(1).
|
122
|
+
str_sz = read(1).unpack1("C")
|
115
123
|
ret = @buffy.slice(@idx, str_sz)
|
116
124
|
raise IncompleteBufferException if @idx + str_sz + 1 >= @buffy.bytesize
|
125
|
+
|
117
126
|
@idx += str_sz
|
118
127
|
if @buffy[@idx].ord != 0
|
119
128
|
raise InvalidPacketException, "Type is not nul-terminated"
|
120
129
|
end
|
130
|
+
|
121
131
|
@idx += 1
|
122
132
|
# no exception, see check above
|
123
133
|
ret
|
@@ -129,29 +139,29 @@ module DBus
|
|
129
139
|
packet = nil
|
130
140
|
case signature.sigtype
|
131
141
|
when Type::BYTE
|
132
|
-
packet = read(1).
|
142
|
+
packet = read(1).unpack1("C")
|
133
143
|
when Type::UINT16
|
134
144
|
align(2)
|
135
|
-
packet = read(2).
|
145
|
+
packet = read(2).unpack1(@uint16)
|
136
146
|
when Type::INT16
|
137
147
|
align(2)
|
138
|
-
packet = read(2).
|
148
|
+
packet = read(2).unpack1(@uint16)
|
139
149
|
if (packet & 0x8000) != 0
|
140
150
|
packet -= 0x10000
|
141
151
|
end
|
142
152
|
when Type::UINT32, Type::UNIX_FD
|
143
153
|
align(4)
|
144
|
-
packet = read(4).
|
154
|
+
packet = read(4).unpack1(@uint32)
|
145
155
|
when Type::INT32
|
146
156
|
align(4)
|
147
|
-
packet = read(4).
|
157
|
+
packet = read(4).unpack1(@uint32)
|
148
158
|
if (packet & 0x80000000) != 0
|
149
159
|
packet -= 0x100000000
|
150
160
|
end
|
151
161
|
when Type::UINT64
|
152
162
|
align(8)
|
153
|
-
packet_l = read(4).
|
154
|
-
packet_h = read(4).
|
163
|
+
packet_l = read(4).unpack1(@uint32)
|
164
|
+
packet_h = read(4).unpack1(@uint32)
|
155
165
|
packet = if @endianness == LIL_END
|
156
166
|
packet_l + packet_h * 2**32
|
157
167
|
else
|
@@ -159,8 +169,8 @@ module DBus
|
|
159
169
|
end
|
160
170
|
when Type::INT64
|
161
171
|
align(8)
|
162
|
-
packet_l = read(4).
|
163
|
-
packet_h = read(4).
|
172
|
+
packet_l = read(4).unpack1(@uint32)
|
173
|
+
packet_h = read(4).unpack1(@uint32)
|
164
174
|
packet = if @endianness == LIL_END
|
165
175
|
packet_l + packet_h * 2**32
|
166
176
|
else
|
@@ -171,16 +181,17 @@ module DBus
|
|
171
181
|
end
|
172
182
|
when Type::DOUBLE
|
173
183
|
align(8)
|
174
|
-
packet = read(8).
|
184
|
+
packet = read(8).unpack1(@double)
|
175
185
|
when Type::BOOLEAN
|
176
186
|
align(4)
|
177
|
-
v = read(4).
|
187
|
+
v = read(4).unpack1(@uint32)
|
178
188
|
raise InvalidPacketException if ![0, 1].member?(v)
|
189
|
+
|
179
190
|
packet = (v == 1)
|
180
191
|
when Type::ARRAY
|
181
192
|
align(4)
|
182
193
|
# checks please
|
183
|
-
array_sz = read(4).
|
194
|
+
array_sz = read(4).unpack1(@uint32)
|
184
195
|
raise InvalidPacketException if array_sz > 67_108_864
|
185
196
|
|
186
197
|
align(signature.child.alignment)
|
@@ -201,6 +212,7 @@ module DBus
|
|
201
212
|
signature.members.each do |elem|
|
202
213
|
packet << do_parse(elem)
|
203
214
|
end
|
215
|
+
packet.freeze
|
204
216
|
when Type::VARIANT
|
205
217
|
string = read_signature
|
206
218
|
# error checking please
|
@@ -224,8 +236,8 @@ module DBus
|
|
224
236
|
"sigtype: #{signature.sigtype} (#{signature.sigtype.chr})"
|
225
237
|
end
|
226
238
|
packet
|
227
|
-
end
|
228
|
-
end
|
239
|
+
end
|
240
|
+
end
|
229
241
|
|
230
242
|
# D-Bus packet marshaller class
|
231
243
|
#
|
@@ -243,20 +255,21 @@ module DBus
|
|
243
255
|
@offset = offset # for correct alignment of nested marshallers
|
244
256
|
end
|
245
257
|
|
246
|
-
# Round
|
247
|
-
def num_align(
|
248
|
-
case
|
258
|
+
# Round _num_ up to the specified power of two, _alignment_
|
259
|
+
def num_align(num, alignment)
|
260
|
+
case alignment
|
249
261
|
when 1, 2, 4, 8
|
250
|
-
bits =
|
251
|
-
|
262
|
+
bits = alignment - 1
|
263
|
+
num + bits & ~bits
|
252
264
|
else
|
253
|
-
raise "Unsupported alignment"
|
265
|
+
raise ArgumentError, "Unsupported alignment #{alignment}"
|
254
266
|
end
|
255
267
|
end
|
256
268
|
|
257
|
-
# Align the buffer with NULL (\0) bytes on a byte length of
|
258
|
-
def align(
|
259
|
-
|
269
|
+
# Align the buffer with NULL (\0) bytes on a byte length of _alignment_.
|
270
|
+
def align(alignment)
|
271
|
+
pad_count = num_align(@offset + @packet.bytesize, alignment) - @offset
|
272
|
+
@packet = @packet.ljust(pad_count, 0.chr)
|
260
273
|
end
|
261
274
|
|
262
275
|
# Append the the string _str_ itself to the packet.
|
@@ -267,7 +280,7 @@ module DBus
|
|
267
280
|
|
268
281
|
# Append the the signature _signature_ itself to the packet.
|
269
282
|
def append_signature(str)
|
270
|
-
@packet += str.bytesize.chr
|
283
|
+
@packet += "#{str.bytesize.chr}#{str}\u0000"
|
271
284
|
end
|
272
285
|
|
273
286
|
# Append the array type _type_ to the packet and allow for appending
|
@@ -282,6 +295,7 @@ module DBus
|
|
282
295
|
yield
|
283
296
|
sz = @packet.bytesize - contentidx
|
284
297
|
raise InvalidPacketException if sz > 67_108_864
|
298
|
+
|
285
299
|
@packet[sizeidx...sizeidx + 4] = [sz].pack("L")
|
286
300
|
end
|
287
301
|
|
@@ -337,57 +351,24 @@ module DBus
|
|
337
351
|
when Type::SIGNATURE
|
338
352
|
append_signature(val)
|
339
353
|
when Type::VARIANT
|
340
|
-
|
341
|
-
if val.is_a?(Array) && val.size == 2
|
342
|
-
if val[0].is_a?(DBus::Type::Type)
|
343
|
-
vartype, vardata = val
|
344
|
-
elsif val[0].is_a?(String)
|
345
|
-
begin
|
346
|
-
parsed = Type::Parser.new(val[0]).parse
|
347
|
-
vartype = parsed[0] if parsed.size == 1
|
348
|
-
vardata = val[1]
|
349
|
-
rescue Type::SignatureException
|
350
|
-
# no assignment
|
351
|
-
end
|
352
|
-
end
|
353
|
-
end
|
354
|
-
if vartype.nil?
|
355
|
-
vartype, vardata = PacketMarshaller.make_variant(val)
|
356
|
-
vartype = Type::Parser.new(vartype).parse[0]
|
357
|
-
end
|
358
|
-
|
359
|
-
append_signature(vartype.to_s)
|
360
|
-
align(vartype.alignment)
|
361
|
-
sub = PacketMarshaller.new(@offset + @packet.bytesize)
|
362
|
-
sub.append(vartype, vardata)
|
363
|
-
@packet += sub.packet
|
354
|
+
append_variant(val)
|
364
355
|
when Type::ARRAY
|
365
|
-
|
366
|
-
raise TypeException, "Expected an Array but got a Hash" if type.child.sigtype != Type::DICT_ENTRY
|
367
|
-
# Damn ruby rocks here
|
368
|
-
val = val.to_a
|
369
|
-
end
|
370
|
-
# If string is recieved and ay is expected, explode the string
|
371
|
-
if val.is_a?(String) && type.child.sigtype == Type::BYTE
|
372
|
-
val = val.bytes
|
373
|
-
end
|
374
|
-
if !val.is_a?(Enumerable)
|
375
|
-
raise TypeException, "Expected an Enumerable of #{type.child.inspect} but got a #{val.class}"
|
376
|
-
end
|
377
|
-
array(type.child) do
|
378
|
-
val.each do |elem|
|
379
|
-
append(type.child, elem)
|
380
|
-
end
|
381
|
-
end
|
356
|
+
append_array(type.child, val)
|
382
357
|
when Type::STRUCT, Type::DICT_ENTRY
|
383
|
-
|
384
|
-
|
358
|
+
unless val.is_a?(Array) || val.is_a?(Struct)
|
359
|
+
type_name = Type::TYPE_MAPPING[type.sigtype].first
|
360
|
+
raise TypeException, "#{type_name} expects an Array or Struct"
|
361
|
+
end
|
362
|
+
|
385
363
|
if type.sigtype == Type::DICT_ENTRY && val.size != 2
|
386
|
-
raise TypeException, "
|
364
|
+
raise TypeException, "DICT_ENTRY expects a pair"
|
387
365
|
end
|
366
|
+
|
388
367
|
if type.members.size != val.size
|
389
|
-
|
368
|
+
type_name = Type::TYPE_MAPPING[type.sigtype].first
|
369
|
+
raise TypeException, "#{type_name} has #{val.size} elements but type info for #{type.members.size}"
|
390
370
|
end
|
371
|
+
|
391
372
|
struct do
|
392
373
|
type.members.zip(val).each do |t, v|
|
393
374
|
append(t, v)
|
@@ -397,7 +378,58 @@ module DBus
|
|
397
378
|
raise NotImplementedError,
|
398
379
|
"sigtype: #{type.sigtype} (#{type.sigtype.chr})"
|
399
380
|
end
|
400
|
-
end
|
381
|
+
end
|
382
|
+
|
383
|
+
def append_variant(val)
|
384
|
+
vartype = nil
|
385
|
+
if val.is_a?(Array) && val.size == 2
|
386
|
+
case val[0]
|
387
|
+
when DBus::Type::Type
|
388
|
+
vartype, vardata = val
|
389
|
+
when String
|
390
|
+
begin
|
391
|
+
parsed = Type::Parser.new(val[0]).parse
|
392
|
+
vartype = parsed[0] if parsed.size == 1
|
393
|
+
vardata = val[1]
|
394
|
+
rescue Type::SignatureException
|
395
|
+
# no assignment
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
399
|
+
if vartype.nil?
|
400
|
+
vartype, vardata = PacketMarshaller.make_variant(val)
|
401
|
+
vartype = Type::Parser.new(vartype).parse[0]
|
402
|
+
end
|
403
|
+
|
404
|
+
append_signature(vartype.to_s)
|
405
|
+
align(vartype.alignment)
|
406
|
+
sub = PacketMarshaller.new(@offset + @packet.bytesize)
|
407
|
+
sub.append(vartype, vardata)
|
408
|
+
@packet += sub.packet
|
409
|
+
end
|
410
|
+
|
411
|
+
# @param child_type [DBus::Type::Type]
|
412
|
+
def append_array(child_type, val)
|
413
|
+
if val.is_a?(Hash)
|
414
|
+
raise TypeException, "Expected an Array but got a Hash" if child_type.sigtype != Type::DICT_ENTRY
|
415
|
+
|
416
|
+
# Damn ruby rocks here
|
417
|
+
val = val.to_a
|
418
|
+
end
|
419
|
+
# If string is recieved and ay is expected, explode the string
|
420
|
+
if val.is_a?(String) && child_type.sigtype == Type::BYTE
|
421
|
+
val = val.bytes
|
422
|
+
end
|
423
|
+
if !val.is_a?(Enumerable)
|
424
|
+
raise TypeException, "Expected an Enumerable of #{child_type.inspect} but got a #{val.class}"
|
425
|
+
end
|
426
|
+
|
427
|
+
array(child_type) do
|
428
|
+
val.each do |elem|
|
429
|
+
append(child_type, elem)
|
430
|
+
end
|
431
|
+
end
|
432
|
+
end
|
401
433
|
|
402
434
|
# Make a [signature, value] pair for a variant
|
403
435
|
def self.make_variant(value)
|
@@ -429,5 +461,5 @@ module DBus
|
|
429
461
|
end
|
430
462
|
end
|
431
463
|
end
|
432
|
-
end
|
433
|
-
end
|
464
|
+
end
|
465
|
+
end
|
data/lib/dbus/matchrule.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of the ruby-dbus project
|
2
4
|
# Copyright (C) 2007 Arnaud Cornet and Paul van Tilburg
|
3
5
|
#
|
@@ -27,7 +29,7 @@ module DBus
|
|
27
29
|
attr_accessor :path
|
28
30
|
# The destination filter.
|
29
31
|
attr_accessor :destination
|
30
|
-
# The type type that is matched.
|
32
|
+
# @return [String] The type type that is matched.
|
31
33
|
attr_reader :type
|
32
34
|
|
33
35
|
# Create a new match rule
|
@@ -35,13 +37,14 @@ module DBus
|
|
35
37
|
@sender = @interface = @member = @path = @destination = @type = nil
|
36
38
|
end
|
37
39
|
|
38
|
-
# Set the message types to filter to type
|
40
|
+
# Set the message types to filter to type _typ_.
|
39
41
|
# Possible message types are: signal, method_call, method_return, and error.
|
40
|
-
def type=(
|
41
|
-
if !["signal", "method_call", "method_return", "error"].member?(
|
42
|
-
raise MatchRuleException,
|
42
|
+
def type=(typ)
|
43
|
+
if !["signal", "method_call", "method_return", "error"].member?(typ)
|
44
|
+
raise MatchRuleException, typ
|
43
45
|
end
|
44
|
-
|
46
|
+
|
47
|
+
@type = typ
|
45
48
|
end
|
46
49
|
|
47
50
|
# Returns a match rule string version of the object. E.g.:
|
@@ -58,11 +61,13 @@ module DBus
|
|
58
61
|
def from_s(str)
|
59
62
|
str.split(",").each do |eq|
|
60
63
|
next unless eq =~ /^(.*)='([^']*)'$/
|
64
|
+
|
61
65
|
# "
|
62
66
|
name = Regexp.last_match(1)
|
63
67
|
val = Regexp.last_match(2)
|
64
68
|
raise MatchRuleException, name unless FILTERS.member?(name.to_sym)
|
65
|
-
|
69
|
+
|
70
|
+
method("#{name}=").call(val)
|
66
71
|
end
|
67
72
|
self
|
68
73
|
end
|
@@ -80,18 +85,13 @@ module DBus
|
|
80
85
|
|
81
86
|
# Determines whether a message _msg_ matches the match rule.
|
82
87
|
def match(msg)
|
83
|
-
if @type
|
84
|
-
if { Message::SIGNAL => "signal", Message::METHOD_CALL => "method_call",
|
85
|
-
Message::METHOD_RETURN => "method_return",
|
86
|
-
Message::ERROR => "error" }[msg.message_type] != @type
|
87
|
-
return false
|
88
|
-
end
|
89
|
-
end
|
88
|
+
return false if @type && @type != msg.message_type_s
|
90
89
|
return false if @interface && @interface != msg.interface
|
91
90
|
return false if @member && @member != msg.member
|
92
91
|
return false if @path && @path != msg.path
|
92
|
+
|
93
93
|
# FIXME: sender and destination are ignored
|
94
94
|
true
|
95
95
|
end
|
96
|
-
end
|
97
|
-
end
|
96
|
+
end
|
97
|
+
end
|
data/lib/dbus/message.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# dbus.rb - Module containing the low-level D-Bus implementation
|
2
4
|
#
|
3
5
|
# This file is part of the ruby-dbus project
|
@@ -27,7 +29,7 @@ module DBus
|
|
27
29
|
# Mutex that protects updates on the serial number.
|
28
30
|
@@serial_mutex = Mutex.new
|
29
31
|
# Type of a message (by specification).
|
30
|
-
MESSAGE_SIGNATURE = "yyyyuua(yv)"
|
32
|
+
MESSAGE_SIGNATURE = "yyyyuua(yv)"
|
31
33
|
|
32
34
|
# FIXME: following message type constants should be under Message::Type IMO
|
33
35
|
# well, yeah sure
|
@@ -43,6 +45,9 @@ module DBus
|
|
43
45
|
# Signal message type.
|
44
46
|
SIGNAL = 4
|
45
47
|
|
48
|
+
# Names used by signal match rules
|
49
|
+
TYPE_NAMES = ["invalid", "method_call", "method_return", "error", "signal"].freeze
|
50
|
+
|
46
51
|
# Message flag signyfing that no reply is expected.
|
47
52
|
NO_REPLY_EXPECTED = 0x1
|
48
53
|
# Message flag signifying that no automatic start is required/must be
|
@@ -66,11 +71,13 @@ module DBus
|
|
66
71
|
attr_accessor :sender
|
67
72
|
# The signature of the message contents.
|
68
73
|
attr_accessor :signature
|
69
|
-
#
|
74
|
+
# @return [Integer] (u32)
|
75
|
+
# The serial number of the message this message is a reply for.
|
70
76
|
attr_accessor :reply_serial
|
71
77
|
# The protocol.
|
72
78
|
attr_reader :protocol
|
73
|
-
#
|
79
|
+
# @return [Integer] (u32)
|
80
|
+
# The serial of the message.
|
74
81
|
attr_reader :serial
|
75
82
|
# The parameters of the message.
|
76
83
|
attr_reader :params
|
@@ -105,22 +112,28 @@ module DBus
|
|
105
112
|
"error_name=#{error_name}"
|
106
113
|
end
|
107
114
|
|
108
|
-
#
|
109
|
-
|
110
|
-
|
115
|
+
# @return [String] name of message type, as used in match rules:
|
116
|
+
# "method_call", "method_return", "signal", "error"
|
117
|
+
def message_type_s
|
118
|
+
TYPE_NAMES[message_type] || "unknown_type_#{message_type}"
|
111
119
|
end
|
112
120
|
|
113
|
-
# Create
|
114
|
-
def self.
|
115
|
-
|
121
|
+
# Create a regular reply to a message _msg_.
|
122
|
+
def self.method_return(msg)
|
123
|
+
MethodReturnMessage.new.reply_to(msg)
|
116
124
|
end
|
117
125
|
|
118
|
-
#
|
119
|
-
|
126
|
+
# Create an error reply to a message _msg_.
|
127
|
+
def self.error(msg, error_name, description = nil)
|
128
|
+
ErrorMessage.new(error_name, description).reply_to(msg)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Mark this message as a reply to a another message _msg_, taking
|
132
|
+
# the serial number of _msg_ as reply serial and the sender of _msg_ as
|
120
133
|
# destination.
|
121
|
-
def reply_to(
|
122
|
-
@reply_serial =
|
123
|
-
@destination =
|
134
|
+
def reply_to(msg)
|
135
|
+
@reply_serial = msg.serial
|
136
|
+
@destination = msg.sender
|
124
137
|
self
|
125
138
|
end
|
126
139
|
|
@@ -223,7 +236,7 @@ module DBus
|
|
223
236
|
end
|
224
237
|
end
|
225
238
|
pu.align(8)
|
226
|
-
if @body_length
|
239
|
+
if @body_length.positive? && @signature
|
227
240
|
@params = pu.unmarshall(@signature, @body_length)
|
228
241
|
end
|
229
242
|
[self, pu.idx]
|
@@ -231,12 +244,12 @@ module DBus
|
|
231
244
|
|
232
245
|
# Make a new exception from ex, mark it as being caused by this message
|
233
246
|
# @api private
|
234
|
-
def annotate_exception(
|
235
|
-
|
236
|
-
|
237
|
-
|
247
|
+
def annotate_exception(exc)
|
248
|
+
new_exc = exc.exception("#{exc}; caused by #{self}")
|
249
|
+
new_exc.set_backtrace(exc.backtrace)
|
250
|
+
new_exc
|
238
251
|
end
|
239
|
-
end
|
252
|
+
end
|
240
253
|
|
241
254
|
class MethodReturnMessage < Message
|
242
255
|
def initialize
|
@@ -251,17 +264,17 @@ module DBus
|
|
251
264
|
add_param(Type::STRING, description) unless description.nil?
|
252
265
|
end
|
253
266
|
|
254
|
-
def self.from_exception(
|
255
|
-
name = if
|
256
|
-
|
267
|
+
def self.from_exception(exc)
|
268
|
+
name = if exc.is_a? DBus::Error
|
269
|
+
exc.name
|
257
270
|
else
|
258
271
|
"org.freedesktop.DBus.Error.Failed"
|
259
|
-
#
|
272
|
+
# exc.class.to_s # RuntimeError is not a valid name, has no dot
|
260
273
|
end
|
261
|
-
description =
|
274
|
+
description = exc.message
|
262
275
|
msg = new(name, description)
|
263
|
-
msg.add_param(DBus.type("as"),
|
276
|
+
msg.add_param(DBus.type("as"), exc.backtrace)
|
264
277
|
msg
|
265
278
|
end
|
266
279
|
end
|
267
|
-
end
|
280
|
+
end
|
data/lib/dbus/message_queue.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of the ruby-dbus project
|
2
4
|
# Copyright (C) 2007 Arnaud Cornet and Paul van Tilburg
|
3
5
|
# Copyright (C) 2009-2014 Martin Vidner
|
@@ -23,14 +25,16 @@ module DBus
|
|
23
25
|
connect
|
24
26
|
end
|
25
27
|
|
26
|
-
# @param
|
28
|
+
# @param blocking [Boolean]
|
29
|
+
# true: wait to return a {Message};
|
30
|
+
# false: may return `nil`
|
27
31
|
# @return [Message,nil] one message or nil if unavailable
|
28
32
|
# @raise EOFError
|
29
33
|
# @todo failure modes
|
30
|
-
def pop(
|
34
|
+
def pop(blocking: true)
|
31
35
|
buffer_from_socket_nonblock
|
32
36
|
message = message_from_buffer_nonblock
|
33
|
-
|
37
|
+
if blocking
|
34
38
|
# we can block
|
35
39
|
while message.nil?
|
36
40
|
r, _d, _d = IO.select([@socket])
|
@@ -54,7 +58,7 @@ module DBus
|
|
54
58
|
def connect
|
55
59
|
addresses = @address.split ";"
|
56
60
|
# connect to first one that succeeds
|
57
|
-
|
61
|
+
addresses.find do |a|
|
58
62
|
transport, keyvaluestring = a.split ":"
|
59
63
|
kv_list = keyvaluestring.split ","
|
60
64
|
kv_hash = {}
|
@@ -74,7 +78,6 @@ module DBus
|
|
74
78
|
# ignore, report?
|
75
79
|
end
|
76
80
|
end
|
77
|
-
worked
|
78
81
|
# returns the address that worked or nil.
|
79
82
|
# how to report failure?
|
80
83
|
end
|
@@ -136,6 +139,7 @@ module DBus
|
|
136
139
|
# @return [Message,nil] the message or nil if unavailable
|
137
140
|
def message_from_buffer_nonblock
|
138
141
|
return nil if @buffer.empty?
|
142
|
+
|
139
143
|
ret = nil
|
140
144
|
begin
|
141
145
|
ret, size = Message.new.unmarshall_buffer(@buffer)
|
@@ -162,6 +166,7 @@ module DBus
|
|
162
166
|
rescue Exception => e
|
163
167
|
puts "Oops:", e
|
164
168
|
raise if @is_tcp # why?
|
169
|
+
|
165
170
|
puts "WARNING: read_nonblock failed, falling back to .recv"
|
166
171
|
@buffer += @socket.recv(MSG_BUF_SIZE)
|
167
172
|
end
|