ruby-dbus 0.15.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 +5 -5
- data/NEWS.md +41 -1
- data/README.md +3 -5
- data/Rakefile +18 -8
- data/VERSION +1 -1
- data/doc/Reference.md +93 -3
- data/examples/doc/_extract_examples +7 -0
- data/examples/gdbus/gdbus +31 -24
- 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 +2 -1
- 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 +20 -15
- data/lib/dbus/bus.rb +129 -74
- data/lib/dbus/bus_name.rb +31 -0
- data/lib/dbus/core_ext/class/attribute.rb +1 -1
- data/lib/dbus/error.rb +4 -2
- data/lib/dbus/introspect.rb +90 -34
- data/lib/dbus/logger.rb +3 -1
- data/lib/dbus/marshall.rb +119 -87
- data/lib/dbus/matchrule.rb +16 -16
- data/lib/dbus/message.rb +40 -27
- data/lib/dbus/message_queue.rb +26 -18
- data/lib/dbus/object.rb +401 -0
- data/lib/dbus/object_path.rb +28 -0
- data/lib/dbus/proxy_object.rb +23 -2
- data/lib/dbus/proxy_object_factory.rb +11 -7
- data/lib/dbus/proxy_object_interface.rb +26 -21
- data/lib/dbus/type.rb +59 -34
- data/lib/dbus/xml.rb +28 -17
- data/lib/dbus.rb +10 -8
- data/ruby-dbus.gemspec +8 -4
- 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 +27 -0
- data/spec/bus_spec.rb +2 -0
- data/spec/byte_array_spec.rb +2 -0
- data/spec/client_robustness_spec.rb +27 -0
- 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 +3 -1
- data/spec/node_spec.rb +23 -0
- data/spec/object_path_spec.rb +25 -0
- data/spec/property_spec.rb +64 -5
- 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 +39 -70
- data/spec/session_bus_spec.rb +3 -1
- data/spec/session_bus_spec_manual.rb +2 -0
- data/spec/signal_spec.rb +5 -3
- data/spec/spec_helper.rb +23 -9
- data/spec/thread_safety_spec.rb +2 -0
- data/spec/tools/dbus-limited-session.conf +4 -0
- data/spec/type_spec.rb +2 -0
- data/spec/value_spec.rb +16 -1
- data/spec/variant_spec.rb +4 -2
- metadata +32 -12
- data/lib/dbus/export.rb +0 -131
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
|
@@ -11,6 +13,7 @@ require "fcntl"
|
|
11
13
|
require "socket"
|
12
14
|
|
13
15
|
module DBus
|
16
|
+
# Encapsulates a socket so that we can {#push} and {#pop} {Message}s.
|
14
17
|
class MessageQueue
|
15
18
|
# The socket that is used to connect with the bus.
|
16
19
|
attr_reader :socket
|
@@ -22,14 +25,16 @@ module DBus
|
|
22
25
|
connect
|
23
26
|
end
|
24
27
|
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
|
28
|
+
# @param blocking [Boolean]
|
29
|
+
# true: wait to return a {Message};
|
30
|
+
# false: may return `nil`
|
31
|
+
# @return [Message,nil] one message or nil if unavailable
|
32
|
+
# @raise EOFError
|
33
|
+
# @todo failure modes
|
34
|
+
def pop(blocking: true)
|
30
35
|
buffer_from_socket_nonblock
|
31
36
|
message = message_from_buffer_nonblock
|
32
|
-
|
37
|
+
if blocking
|
33
38
|
# we can block
|
34
39
|
while message.nil?
|
35
40
|
r, _d, _d = IO.select([@socket])
|
@@ -53,7 +58,7 @@ module DBus
|
|
53
58
|
def connect
|
54
59
|
addresses = @address.split ";"
|
55
60
|
# connect to first one that succeeds
|
56
|
-
|
61
|
+
addresses.find do |a|
|
57
62
|
transport, keyvaluestring = a.split ":"
|
58
63
|
kv_list = keyvaluestring.split ","
|
59
64
|
kv_hash = {}
|
@@ -73,29 +78,29 @@ module DBus
|
|
73
78
|
# ignore, report?
|
74
79
|
end
|
75
80
|
end
|
76
|
-
worked
|
77
81
|
# returns the address that worked or nil.
|
78
82
|
# how to report failure?
|
79
83
|
end
|
80
84
|
|
81
85
|
# Connect to a bus over tcp and initialize the connection.
|
82
86
|
def connect_to_tcp(params)
|
83
|
-
|
84
|
-
|
87
|
+
host = params["host"]
|
88
|
+
port = params["port"]
|
89
|
+
if host && port
|
85
90
|
begin
|
86
91
|
# initialize the tcp socket
|
87
|
-
@socket = TCPSocket.new(
|
92
|
+
@socket = TCPSocket.new(host, port.to_i)
|
88
93
|
@socket.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
89
94
|
init_connection
|
90
95
|
@is_tcp = true
|
91
96
|
rescue Exception => e
|
92
97
|
puts "Oops:", e
|
93
|
-
puts "Error: Could not establish connection to: #{
|
98
|
+
puts "Error: Could not establish connection to: #{host}:#{port}, will now exit."
|
94
99
|
exit(1) # a little harsh
|
95
100
|
end
|
96
101
|
else
|
97
102
|
# Danger, Will Robinson: the specified "path" is not usable
|
98
|
-
puts "Error: supplied
|
103
|
+
puts "Error: supplied params: #{@params}, unusable! sorry."
|
99
104
|
end
|
100
105
|
end
|
101
106
|
|
@@ -124,22 +129,23 @@ module DBus
|
|
124
129
|
|
125
130
|
# Initialize the connection to the bus.
|
126
131
|
def init_connection
|
127
|
-
|
128
|
-
|
132
|
+
client = Client.new(@socket)
|
133
|
+
client.authenticate
|
129
134
|
end
|
130
135
|
|
131
136
|
public # FIXME: fix Main loop instead
|
132
137
|
|
133
138
|
# Get and remove one message from the buffer.
|
134
|
-
#
|
139
|
+
# @return [Message,nil] the message or nil if unavailable
|
135
140
|
def message_from_buffer_nonblock
|
136
141
|
return nil if @buffer.empty?
|
142
|
+
|
137
143
|
ret = nil
|
138
144
|
begin
|
139
145
|
ret, size = Message.new.unmarshall_buffer(@buffer)
|
140
146
|
@buffer.slice!(0, size)
|
141
147
|
rescue IncompleteBufferException
|
142
|
-
# fall through, let ret
|
148
|
+
# fall through, let ret remain nil
|
143
149
|
end
|
144
150
|
ret
|
145
151
|
end
|
@@ -149,7 +155,8 @@ module DBus
|
|
149
155
|
|
150
156
|
# Fill (append) the buffer from data that might be available on the
|
151
157
|
# socket.
|
152
|
-
#
|
158
|
+
# @return [void]
|
159
|
+
# @raise EOFError
|
153
160
|
def buffer_from_socket_nonblock
|
154
161
|
@buffer += @socket.read_nonblock(MSG_BUF_SIZE)
|
155
162
|
rescue EOFError
|
@@ -159,6 +166,7 @@ module DBus
|
|
159
166
|
rescue Exception => e
|
160
167
|
puts "Oops:", e
|
161
168
|
raise if @is_tcp # why?
|
169
|
+
|
162
170
|
puts "WARNING: read_nonblock failed, falling back to .recv"
|
163
171
|
@buffer += @socket.recv(MSG_BUF_SIZE)
|
164
172
|
end
|