ruby-dbus 0.16.0 → 0.18.1

Sign up to get free protection for your applications and to get access to all the features.
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