ruby-dbus 0.16.0 → 0.18.1

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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +160 -0
  3. data/README.md +3 -5
  4. data/Rakefile +18 -8
  5. data/VERSION +1 -1
  6. data/doc/Reference.md +106 -7
  7. data/examples/doc/_extract_examples +7 -0
  8. data/examples/gdbus/gdbus +31 -24
  9. data/examples/no-introspect/nm-test.rb +2 -0
  10. data/examples/no-introspect/tracker-test.rb +3 -1
  11. data/examples/rhythmbox/playpause.rb +2 -1
  12. data/examples/service/call_service.rb +2 -1
  13. data/examples/service/complex-property.rb +21 -0
  14. data/examples/service/service_newapi.rb +1 -1
  15. data/examples/simple/call_introspect.rb +1 -0
  16. data/examples/simple/get_id.rb +2 -1
  17. data/examples/simple/properties.rb +2 -0
  18. data/examples/utils/listnames.rb +1 -0
  19. data/examples/utils/notify.rb +1 -0
  20. data/lib/dbus/api_options.rb +9 -0
  21. data/lib/dbus/auth.rb +20 -15
  22. data/lib/dbus/bus.rb +123 -75
  23. data/lib/dbus/bus_name.rb +12 -8
  24. data/lib/dbus/core_ext/class/attribute.rb +1 -1
  25. data/lib/dbus/data.rb +821 -0
  26. data/lib/dbus/emits_changed_signal.rb +83 -0
  27. data/lib/dbus/error.rb +4 -2
  28. data/lib/dbus/introspect.rb +132 -31
  29. data/lib/dbus/logger.rb +3 -1
  30. data/lib/dbus/marshall.rb +247 -296
  31. data/lib/dbus/matchrule.rb +16 -16
  32. data/lib/dbus/message.rb +44 -37
  33. data/lib/dbus/message_queue.rb +16 -10
  34. data/lib/dbus/object.rb +358 -24
  35. data/lib/dbus/object_path.rb +11 -6
  36. data/lib/dbus/proxy_object.rb +22 -1
  37. data/lib/dbus/proxy_object_factory.rb +13 -7
  38. data/lib/dbus/proxy_object_interface.rb +63 -30
  39. data/lib/dbus/raw_message.rb +91 -0
  40. data/lib/dbus/type.rb +318 -86
  41. data/lib/dbus/xml.rb +32 -17
  42. data/lib/dbus.rb +14 -7
  43. data/ruby-dbus.gemspec +7 -3
  44. data/spec/async_spec.rb +2 -0
  45. data/spec/binding_spec.rb +2 -0
  46. data/spec/bus_and_xml_backend_spec.rb +2 -0
  47. data/spec/bus_driver_spec.rb +2 -0
  48. data/spec/bus_name_spec.rb +3 -1
  49. data/spec/bus_spec.rb +2 -0
  50. data/spec/byte_array_spec.rb +2 -0
  51. data/spec/client_robustness_spec.rb +4 -2
  52. data/spec/data/marshall.yaml +1667 -0
  53. data/spec/data_spec.rb +673 -0
  54. data/spec/emits_changed_signal_spec.rb +58 -0
  55. data/spec/err_msg_spec.rb +2 -0
  56. data/spec/introspect_xml_parser_spec.rb +2 -0
  57. data/spec/introspection_spec.rb +2 -0
  58. data/spec/main_loop_spec.rb +3 -1
  59. data/spec/node_spec.rb +23 -0
  60. data/spec/object_path_spec.rb +3 -0
  61. data/spec/object_spec.rb +138 -0
  62. data/spec/packet_marshaller_spec.rb +41 -0
  63. data/spec/packet_unmarshaller_spec.rb +248 -0
  64. data/spec/property_spec.rb +192 -5
  65. data/spec/proxy_object_spec.rb +2 -0
  66. data/spec/server_robustness_spec.rb +2 -0
  67. data/spec/server_spec.rb +2 -0
  68. data/spec/service_newapi.rb +70 -70
  69. data/spec/session_bus_spec.rb +3 -1
  70. data/spec/session_bus_spec_manual.rb +2 -0
  71. data/spec/signal_spec.rb +5 -3
  72. data/spec/spec_helper.rb +37 -9
  73. data/spec/thread_safety_spec.rb +2 -0
  74. data/spec/tools/dbus-limited-session.conf +4 -0
  75. data/spec/type_spec.rb +214 -6
  76. data/spec/value_spec.rb +16 -1
  77. data/spec/variant_spec.rb +4 -2
  78. data/spec/zzz_quit_spec.rb +16 -0
  79. metadata +34 -8
@@ -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 _t_.
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=(t)
41
- if !["signal", "method_call", "method_return", "error"].member?(t)
42
- raise MatchRuleException, t
42
+ def type=(typ)
43
+ if !["signal", "method_call", "method_return", "error"].member?(typ)
44
+ raise MatchRuleException, typ
43
45
  end
44
- @type = t
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
- method(name + "=").call(val)
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 # class MatchRule
97
- end # module D-Bus
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)".freeze
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
- # The serial number of the message this message is a reply for.
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
- # The serial of the message.
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
- # Create a regular reply to a message _m_.
109
- def self.method_return(m)
110
- MethodReturnMessage.new.reply_to(m)
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 an error reply to a message _m_.
114
- def self.error(m, error_name, description = nil)
115
- ErrorMessage.new(error_name, description).reply_to(m)
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
- # Mark this message as a reply to a another message _m_, taking
119
- # the serial number of _m_ as reply serial and the sender of _m_ as
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(m)
122
- @reply_serial = m.serial
123
- @destination = m.sender
134
+ def reply_to(msg)
135
+ @reply_serial = msg.serial
136
+ @destination = msg.sender
124
137
  self
125
138
  end
126
139
 
@@ -159,7 +172,7 @@ module DBus
159
172
  @body_length = params.packet.bytesize
160
173
 
161
174
  marshaller = PacketMarshaller.new
162
- marshaller.append(Type::BYTE, HOST_END)
175
+ marshaller.append(Type::BYTE, HOST_END.ord)
163
176
  marshaller.append(Type::BYTE, @message_type)
164
177
  marshaller.append(Type::BYTE, @flags)
165
178
  marshaller.append(Type::BYTE, @protocol)
@@ -191,13 +204,7 @@ module DBus
191
204
  # the detected message (self) and
192
205
  # the index pointer of the buffer where the message data ended.
193
206
  def unmarshall_buffer(buf)
194
- buf = buf.dup
195
- endianness = if buf[0] == "l"
196
- LIL_END
197
- else
198
- BIG_END
199
- end
200
- pu = PacketUnmarshaller.new(buf, endianness)
207
+ pu = PacketUnmarshaller.new(buf, RawMessage.endianness(buf[0]))
201
208
  mdata = pu.unmarshall(MESSAGE_SIGNATURE)
202
209
  _, @message_type, @flags, @protocol, @body_length, @serial,
203
210
  headers = mdata
@@ -222,21 +229,21 @@ module DBus
222
229
  @signature = struct[1]
223
230
  end
224
231
  end
225
- pu.align(8)
226
- if @body_length > 0 && @signature
232
+ pu.align_body
233
+ if @body_length.positive? && @signature
227
234
  @params = pu.unmarshall(@signature, @body_length)
228
235
  end
229
- [self, pu.idx]
236
+ [self, pu.consumed_size]
230
237
  end
231
238
 
232
239
  # Make a new exception from ex, mark it as being caused by this message
233
240
  # @api private
234
- def annotate_exception(ex)
235
- new_ex = ex.exception("#{ex}; caused by #{self}")
236
- new_ex.set_backtrace(ex.backtrace)
237
- new_ex
241
+ def annotate_exception(exc)
242
+ new_exc = exc.exception("#{exc}; caused by #{self}")
243
+ new_exc.set_backtrace(exc.backtrace)
244
+ new_exc
238
245
  end
239
- end # class Message
246
+ end
240
247
 
241
248
  class MethodReturnMessage < Message
242
249
  def initialize
@@ -251,17 +258,17 @@ module DBus
251
258
  add_param(Type::STRING, description) unless description.nil?
252
259
  end
253
260
 
254
- def self.from_exception(ex)
255
- name = if ex.is_a? DBus::Error
256
- ex.name
261
+ def self.from_exception(exc)
262
+ name = if exc.is_a? DBus::Error
263
+ exc.name
257
264
  else
258
265
  "org.freedesktop.DBus.Error.Failed"
259
- # ex.class.to_s # RuntimeError is not a valid name, has no dot
266
+ # exc.class.to_s # RuntimeError is not a valid name, has no dot
260
267
  end
261
- description = ex.message
268
+ description = exc.message
262
269
  msg = new(name, description)
263
- msg.add_param(DBus.type("as"), ex.backtrace)
270
+ msg.add_param(DBus.type("as"), exc.backtrace)
264
271
  msg
265
272
  end
266
273
  end
267
- end # module DBus
274
+ end
@@ -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 non_block [Boolean] if true, return nil instead of waiting
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(non_block = false)
34
+ def pop(blocking: true)
31
35
  buffer_from_socket_nonblock
32
36
  message = message_from_buffer_nonblock
33
- unless non_block
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
- worked = addresses.find do |a|
61
+ addresses.find do |a|
58
62
  transport, keyvaluestring = a.split ":"
59
63
  kv_list = keyvaluestring.split ","
60
64
  kv_hash = {}
@@ -74,29 +78,29 @@ 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
81
84
 
82
85
  # Connect to a bus over tcp and initialize the connection.
83
86
  def connect_to_tcp(params)
84
- # check if the path is sufficient
85
- if params.key?("host") && params.key?("port")
87
+ host = params["host"]
88
+ port = params["port"]
89
+ if host && port
86
90
  begin
87
91
  # initialize the tcp socket
88
- @socket = TCPSocket.new(params["host"], params["port"].to_i)
92
+ @socket = TCPSocket.new(host, port.to_i)
89
93
  @socket.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
90
94
  init_connection
91
95
  @is_tcp = true
92
96
  rescue Exception => e
93
97
  puts "Oops:", e
94
- puts "Error: Could not establish connection to: #{@path}, will now exit."
98
+ puts "Error: Could not establish connection to: #{host}:#{port}, will now exit."
95
99
  exit(1) # a little harsh
96
100
  end
97
101
  else
98
102
  # Danger, Will Robinson: the specified "path" is not usable
99
- puts "Error: supplied path: #{@path}, unusable! sorry."
103
+ puts "Error: supplied params: #{@params}, unusable! sorry."
100
104
  end
101
105
  end
102
106
 
@@ -135,6 +139,7 @@ module DBus
135
139
  # @return [Message,nil] the message or nil if unavailable
136
140
  def message_from_buffer_nonblock
137
141
  return nil if @buffer.empty?
142
+
138
143
  ret = nil
139
144
  begin
140
145
  ret, size = Message.new.unmarshall_buffer(@buffer)
@@ -161,6 +166,7 @@ module DBus
161
166
  rescue Exception => e
162
167
  puts "Oops:", e
163
168
  raise if @is_tcp # why?
169
+
164
170
  puts "WARNING: read_nonblock failed, falling back to .recv"
165
171
  @buffer += @socket.recv(MSG_BUF_SIZE)
166
172
  end