ruby-dbus 0.17.0 → 0.18.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|