ruby-dbus 0.22.1 → 0.23.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9faf3489c1ee5baf70dbb2204b777c577d6237554f072fa44bfdbee49c34e06d
4
- data.tar.gz: '08c81cc0acde47f38e19b107222692253fe1b512c7f1bb5698e074c63601b85b'
3
+ metadata.gz: bfebbc3384d221039f465d964817aad4c42ccc147ed6351b23728665c200a9b8
4
+ data.tar.gz: 63e5542cd3f7a76dc0d7fc0d852e7fae9c0f506fdbc06f7b2d1f644267cead46
5
5
  SHA512:
6
- metadata.gz: bf539a91b1420631d7614b83636502f4c41e4ff7f137fb2c54eff88bc6b2810bb53efa14cadd8a5bb28b71864abbb0cd35451202c60f83a78b3e58816aa6fb67
7
- data.tar.gz: aa1e225fe3177c63761d8e487b70a688b45330e4f115aa52753fc08f4f194949a206da8e1d102c3f55f49d169a2688bed67d5497639e3da9652f887f3bad5768
6
+ metadata.gz: 5dea8b83e62b698162f53d18fbc29b60fb594962a449f5d7b8cf82aa10e47fee3633186f894b6d95a42b1d02bc6f5ef172809405e93f57c2b04b450f1fb85732
7
+ data.tar.gz: 3f0de7019ee46470c4e4afc2f37b4badeab5a1387c6d14c1df2b42b271c7bec9656dad656227e71efdf84d678c88b3394904f2e3c810270aaf0bafdb673fe5c3
data/NEWS.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## Ruby D-Bus 0.23.0.beta1 - 2023-06-05
6
+
7
+ Bug fixes:
8
+ * A service can now have more than one name ([#69][]).
9
+ Connection#request_service is deprecated in favor of Connection#object_server
10
+ and BusConnection#request_name
11
+
12
+ [#69]: https://github.com/mvidner/ruby-dbus/issues/69
13
+
14
+ API:
15
+ * Remove Service, splitting it into ProxyService and ObjectServer
16
+ * Split off BusConnection from Connection
17
+
5
18
  ## Ruby D-Bus 0.22.1 - 2023-05-17
6
19
 
7
20
  Bug fixes:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.22.1
1
+ 0.23.0.beta1
data/doc/Reference.md CHANGED
@@ -24,7 +24,7 @@ is simply "dbus"
24
24
 
25
25
  1. {DBus.session_bus Connect to the session bus};
26
26
  2. {DBus::Connection#[] get the screensaver service}
27
- 3. {DBus::Service#[] and its screensaver object}.
27
+ 3. {DBus::ProxyService#[] and its screensaver object}.
28
28
  4. Call one of its methods in a loop, solving [xkcd#196](http://xkcd.com/196).
29
29
 
30
30
   
@@ -58,7 +58,7 @@ a method proxy always returned an array of values. This was to
58
58
  accomodate the rare cases of a DBus method specifying more than one
59
59
  *out* parameter. For compatibility, the behavior is preserved if you
60
60
  construct a {DBus::ProxyObject} with {DBus::ApiOptions::A0},
61
- which is what {DBus::Service#object} does.
61
+ which is what {DBus::ProxyService#object} does.
62
62
 
63
63
  For nearly all methods you used `Method[0]` or
64
64
  `Method.first`
@@ -340,8 +340,8 @@ for overriding this.
340
340
  obj = Note.new("/net/vidner/Example/Properties")
341
341
 
342
342
  bus = DBus::SessionBus.instance
343
- service = bus.request_service("net.vidner.Example")
344
- service.export(obj)
343
+ bus.object_server.export(obj)
344
+ bus.request_name("net.vidner.Example")
345
345
 
346
346
  main = DBus::Main.new
347
347
  main << bus
@@ -16,6 +16,6 @@ class Test < DBus::Object
16
16
  end
17
17
 
18
18
  bus = DBus::SessionBus.instance
19
- svc = bus.request_service("net.vidner.Scratch")
20
- svc.export(Test.new("/net/vidner/Scratch"))
19
+ bus.object_server.export(Test.new("/net/vidner/Scratch"))
20
+ bus.request_name("net.vidner.Scratch")
21
21
  DBus::Main.new.tap { |m| m << bus }.run
@@ -31,9 +31,9 @@ class Test < DBus::Object
31
31
  end
32
32
 
33
33
  bus = DBus::SessionBus.instance
34
- service = bus.request_service("org.ruby.service")
35
34
  myobj = Test.new("/org/ruby/MyInstance")
36
- service.export(myobj)
35
+ bus.object_server.export(myobj)
36
+ bus.request_name("org.ruby.service")
37
37
 
38
38
  Thread.new do
39
39
  i = 0
data/lib/dbus/bus.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  # This file is part of the ruby-dbus project
6
6
  # Copyright (C) 2007 Arnaud Cornet and Paul van Tilburg
7
7
  #
8
- # This library is free software; you caan redistribute it and/or
8
+ # This library is free software; you can redistribute it and/or
9
9
  # modify it under the terms of the GNU Lesser General Public
10
10
  # License, version 2.1 as published by the Free Software Foundation.
11
11
  # See the file "COPYING" for the exact licensing terms.
@@ -17,233 +17,6 @@ require "singleton"
17
17
  #
18
18
  # Module containing all the D-Bus modules and classes.
19
19
  module DBus
20
- # This represents a remote service. It should not be instantiated directly
21
- # Use {Connection#service}
22
- class Service
23
- # The service name.
24
- attr_reader :name
25
- # The bus the service is running on.
26
- attr_reader :bus
27
- # The service root (FIXME).
28
- attr_reader :root
29
-
30
- # Create a new service with a given _name_ on a given _bus_.
31
- def initialize(name, bus)
32
- @name = BusName.new(name)
33
- @bus = bus
34
- @root = Node.new("/")
35
- end
36
-
37
- # Determine whether the service name already exists.
38
- def exists?
39
- bus.proxy.ListNames[0].member?(@name)
40
- end
41
-
42
- # Perform an introspection on all the objects on the service
43
- # (starting recursively from the root).
44
- def introspect
45
- raise NotImplementedError if block_given?
46
-
47
- rec_introspect(@root, "/")
48
- self
49
- end
50
-
51
- # Retrieves an object at the given _path_.
52
- # @param path [ObjectPath]
53
- # @return [ProxyObject]
54
- def [](path)
55
- object(path, api: ApiOptions::A1)
56
- end
57
-
58
- # Retrieves an object at the given _path_
59
- # whose methods always return an array.
60
- # @param path [ObjectPath]
61
- # @param api [ApiOptions]
62
- # @return [ProxyObject]
63
- def object(path, api: ApiOptions::A0)
64
- node = get_node(path, create: true)
65
- if node.object.nil? || node.object.api != api
66
- node.object = ProxyObject.new(
67
- @bus, @name, path,
68
- api: api
69
- )
70
- end
71
- node.object
72
- end
73
-
74
- # Export an object
75
- # @param obj [DBus::Object]
76
- def export(obj)
77
- obj.service = self
78
- get_node(obj.path, create: true).object = obj
79
- object_manager_for(obj)&.object_added(obj)
80
- end
81
-
82
- # Undo exporting an object _obj_.
83
- # Raises ArgumentError if it is not a DBus::Object.
84
- # Returns the object, or false if _obj_ was not exported.
85
- # @param obj [DBus::Object]
86
- def unexport(obj)
87
- raise ArgumentError, "DBus::Service#unexport() expects a DBus::Object argument" unless obj.is_a?(DBus::Object)
88
- return false unless obj.path
89
-
90
- last_path_separator_idx = obj.path.rindex("/")
91
- parent_path = obj.path[1..last_path_separator_idx - 1]
92
- node_name = obj.path[last_path_separator_idx + 1..-1]
93
-
94
- parent_node = get_node(parent_path, create: false)
95
- return false unless parent_node
96
-
97
- object_manager_for(obj)&.object_removed(obj)
98
- obj.service = nil
99
- parent_node.delete(node_name).object
100
- end
101
-
102
- # Get the object node corresponding to the given *path*.
103
- # @param path [ObjectPath]
104
- # @param create [Boolean] if true, the the {Node}s in the path are created
105
- # if they do not already exist.
106
- # @return [Node,nil]
107
- def get_node(path, create: false)
108
- n = @root
109
- path.sub(%r{^/}, "").split("/").each do |elem|
110
- if !(n[elem])
111
- return nil if !create
112
-
113
- n[elem] = Node.new(elem)
114
- end
115
- n = n[elem]
116
- end
117
- n
118
- end
119
-
120
- # Find the (closest) parent of *object*
121
- # implementing the ObjectManager interface, or nil
122
- # @return [DBus::Object,nil]
123
- def object_manager_for(object)
124
- path = object.path
125
- node_chain = get_node_chain(path)
126
- om_node = node_chain.reverse_each.find do |node|
127
- node.object&.is_a? DBus::ObjectManager
128
- end
129
- om_node&.object
130
- end
131
-
132
- # All objects (not paths) under this path (except itself).
133
- # @param path [ObjectPath]
134
- # @return [Array<DBus::Object>]
135
- # @raise ArgumentError if the *path* does not exist
136
- def descendants_for(path)
137
- node = get_node(path, create: false)
138
- raise ArgumentError, "Object path #{path} doesn't exist" if node.nil?
139
-
140
- node.descendant_objects
141
- end
142
-
143
- #########
144
-
145
- private
146
-
147
- #########
148
-
149
- # @raise ArgumentError if the *path* does not exist
150
- def get_node_chain(path)
151
- n = @root
152
- result = [n]
153
- path.sub(%r{^/}, "").split("/").each do |elem|
154
- n = n[elem]
155
- raise ArgumentError, "Object path #{path} doesn't exist" if n.nil?
156
-
157
- result.push(n)
158
- end
159
- result
160
- end
161
-
162
- # Perform a recursive retrospection on the given current _node_
163
- # on the given _path_.
164
- def rec_introspect(node, path)
165
- xml = bus.introspect_data(@name, path)
166
- intfs, subnodes = IntrospectXMLParser.new(xml).parse
167
- subnodes.each do |nodename|
168
- subnode = node[nodename] = Node.new(nodename)
169
- subpath = if path == "/"
170
- "/#{nodename}"
171
- else
172
- "#{path}/#{nodename}"
173
- end
174
- rec_introspect(subnode, subpath)
175
- end
176
- return if intfs.empty?
177
-
178
- node.object = ProxyObjectFactory.new(xml, @bus, @name, path).build
179
- end
180
- end
181
-
182
- # = Object path node class
183
- #
184
- # Class representing a node on an object path.
185
- class Node < Hash
186
- # @return [DBus::Object,DBus::ProxyObject,nil]
187
- # The D-Bus object contained by the node.
188
- attr_accessor :object
189
-
190
- # The name of the node.
191
- # @return [String] the last component of its object path, or "/"
192
- attr_reader :name
193
-
194
- # Create a new node with a given _name_.
195
- def initialize(name)
196
- super()
197
- @name = name
198
- @object = nil
199
- end
200
-
201
- # Return an XML string representation of the node.
202
- # It is shallow, not recursing into subnodes
203
- # @param node_opath [String]
204
- def to_xml(node_opath)
205
- xml = '<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
206
- "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
207
- '
208
- xml += "<node name=\"#{node_opath}\">\n"
209
- each_key do |k|
210
- xml += " <node name=\"#{k}\" />\n"
211
- end
212
- @object&.intfs&.each_value do |v|
213
- xml += v.to_xml
214
- end
215
- xml += "</node>"
216
- xml
217
- end
218
-
219
- # Return inspect information of the node.
220
- def inspect
221
- # Need something here
222
- "<DBus::Node #{sub_inspect}>"
223
- end
224
-
225
- # Return instance inspect information, used by Node#inspect.
226
- def sub_inspect
227
- s = ""
228
- if !@object.nil?
229
- s += format("%x ", @object.object_id)
230
- end
231
- contents_sub_inspect = keys
232
- .map { |k| "#{k} => #{self[k].sub_inspect}" }
233
- .join(",")
234
- "#{s}{#{contents_sub_inspect}}"
235
- end
236
-
237
- # All objects (not paths) under this path (except itself).
238
- # @return [Array<DBus::Object>]
239
- def descendant_objects
240
- children_objects = values.map(&:object).compact
241
- descendants = values.map(&:descendant_objects)
242
- flat_descendants = descendants.reduce([], &:+)
243
- children_objects + flat_descendants
244
- end
245
- end
246
-
247
20
  # FIXME: rename Connection to Bus?
248
21
 
249
22
  # D-Bus main connection class
@@ -279,6 +52,10 @@ module DBus
279
52
  @proxy = nil
280
53
  end
281
54
 
55
+ def object_server
56
+ @object_server ||= ObjectServer.new(self)
57
+ end
58
+
282
59
  # Dispatch all messages that are available in the queue,
283
60
  # but do not block on the queue.
284
61
  # Called by a main loop when something is available in the queue
@@ -487,11 +264,23 @@ module DBus
487
264
  class NameRequestError < Exception
488
265
  end
489
266
 
267
+ def handle_return_of_request_name(ret, name)
268
+ details = if ret == REQUEST_NAME_REPLY_IN_QUEUE
269
+ other = proxy.GetNameOwner(name).first
270
+ other_creds = proxy.GetConnectionCredentials(other).first
271
+ "already owned by #{other}, #{other_creds.inspect}"
272
+ else
273
+ "error code #{ret}"
274
+ end
275
+ raise NameRequestError, "Could not request #{name}, #{details}" unless ret == REQUEST_NAME_REPLY_PRIMARY_OWNER
276
+
277
+ ret
278
+ end
279
+
490
280
  # Attempt to request a service _name_.
491
- #
492
- # FIXME, NameRequestError cannot really be rescued as it will be raised
493
- # when dispatching a later call. Rework the API to better match the spec.
494
- # @return [Service]
281
+ # @raise NameRequestError which cannot really be rescued as it will be raised when dispatching a later call.
282
+ # @return [ObjectServer]
283
+ # @deprecated Use {BusConnection#request_name}.
495
284
  def request_service(name)
496
285
  # Use RequestName, but asynchronously!
497
286
  # A synchronous call would not work with service activation, where
@@ -501,17 +290,9 @@ module DBus
501
290
  # check and report errors first
502
291
  raise rmsg if rmsg.is_a?(Error)
503
292
 
504
- details = if r == REQUEST_NAME_REPLY_IN_QUEUE
505
- other = proxy.GetNameOwner(name).first
506
- other_creds = proxy.GetConnectionCredentials(other).first
507
- "already owned by #{other}, #{other_creds.inspect}"
508
- else
509
- "error code #{r}"
510
- end
511
- raise NameRequestError, "Could not request #{name}, #{details}" unless r == REQUEST_NAME_REPLY_PRIMARY_OWNER
293
+ handle_return_of_request_name(r, name)
512
294
  end
513
- @service = Service.new(name, self)
514
- @service
295
+ object_server
515
296
  end
516
297
 
517
298
  # Set up a ProxyObject for the bus itself, since the bus is introspectable.
@@ -631,7 +412,7 @@ module DBus
631
412
  if msg.path == "/org/freedesktop/DBus"
632
413
  DBus.logger.debug "Got method call on /org/freedesktop/DBus"
633
414
  end
634
- node = @service.get_node(msg.path, create: false)
415
+ node = object_server.get_node(msg.path, create: false)
635
416
  # introspect a known path even if there is no object on it
636
417
  if node &&
637
418
  msg.interface == "org.freedesktop.DBus.Introspectable" &&
@@ -670,24 +451,23 @@ module DBus
670
451
  def service(name)
671
452
  # The service might not exist at this time so we cannot really check
672
453
  # anything
673
- Service.new(name, self)
454
+ ProxyService.new(name, self)
674
455
  end
675
456
  alias [] service
676
457
 
677
458
  # @api private
678
459
  # Emit a signal event for the given _service_, object _obj_, interface
679
460
  # _intf_ and signal _sig_ with arguments _args_.
680
- # @param service [Service]
461
+ # @param _service unused
681
462
  # @param obj [DBus::Object]
682
463
  # @param intf [Interface]
683
464
  # @param sig [Signal]
684
465
  # @param args arguments for the signal
685
- def emit(service, obj, intf, sig, *args)
466
+ def emit(_service, obj, intf, sig, *args)
686
467
  m = Message.new(DBus::Message::SIGNAL)
687
468
  m.path = obj.path
688
469
  m.interface = intf.name
689
470
  m.member = sig.name
690
- m.sender = service.name
691
471
  i = 0
692
472
  sig.params.each do |par|
693
473
  m.add_param(par.type, args[i])
@@ -710,7 +490,25 @@ module DBus
710
490
  @unique_name = rmsg.destination
711
491
  DBus.logger.debug "Got hello reply. Our unique_name is #{@unique_name}"
712
492
  end
713
- @service = Service.new(@unique_name, self)
493
+ end
494
+ end
495
+
496
+ # A regular Bus {Connection}.
497
+ # As opposed to a peer connection to a single counterparty with no daemon in between.
498
+ # FIXME: move the remaining relevant methods from Connection here, but alias the constants
499
+ class BusConnection < Connection
500
+ # @param name [BusName] the requested name
501
+ # @param flags [Integer] TODO: explain and add a better non-numeric API for this
502
+ # @raise NameRequestError if we could not get the name
503
+ # @example Usage
504
+ # bus = DBus.session_bus
505
+ # bus.object_server.export(DBus::Object.new("/org/example/Test"))
506
+ # bus.request_name("org.example.Test")
507
+ # @see https://dbus.freedesktop.org/doc/dbus-specification.html#bus-messages-request-name
508
+ def request_name(name, flags: 0)
509
+ name = BusName.new(name)
510
+ r = proxy.RequestName(name, flags).first
511
+ handle_return_of_request_name(r, name)
714
512
  end
715
513
  end
716
514
 
@@ -720,7 +518,7 @@ module DBus
720
518
  #
721
519
  # Use SessionBus, the non-singleton ASessionBus is
722
520
  # for the test suite.
723
- class ASessionBus < Connection
521
+ class ASessionBus < BusConnection
724
522
  # Get the the default session bus.
725
523
  def initialize
726
524
  super(self.class.session_bus_address)
@@ -771,7 +569,7 @@ module DBus
771
569
  #
772
570
  # Use SystemBus, the non-singleton ASystemBus is
773
571
  # for the test suite.
774
- class ASystemBus < Connection
572
+ class ASystemBus < BusConnection
775
573
  # Get the default system bus.
776
574
  def initialize
777
575
  super(self.class.system_bus_address)
@@ -794,7 +592,8 @@ module DBus
794
592
  #
795
593
  # you'll need to take care about authentification then, more info here:
796
594
  # https://gitlab.com/pangdudu/ruby-dbus/-/blob/master/README.rdoc
797
- class RemoteBus < Connection
595
+ # TODO: keep the name but update the docs
596
+ class RemoteBus < BusConnection
798
597
  # Get the remote bus.
799
598
  def initialize(socket_name)
800
599
  super(socket_name)
@@ -818,55 +617,4 @@ module DBus
818
617
  def self.session_bus
819
618
  SessionBus.instance
820
619
  end
821
-
822
- # = Main event loop class.
823
- #
824
- # Class that takes care of handling message and signal events
825
- # asynchronously. *Note:* This is a native implement and therefore does
826
- # not integrate with a graphical widget set main loop.
827
- class Main
828
- # Create a new main event loop.
829
- def initialize
830
- @buses = {}
831
- @quitting = false
832
- end
833
-
834
- # Add a _bus_ to the list of buses to watch for events.
835
- def <<(bus)
836
- @buses[bus.message_queue.socket] = bus
837
- end
838
-
839
- # Quit a running main loop, to be used eg. from a signal handler
840
- def quit
841
- @quitting = true
842
- end
843
-
844
- # Run the main loop. This is a blocking call!
845
- def run
846
- # before blocking, empty the buffers
847
- # https://bugzilla.novell.com/show_bug.cgi?id=537401
848
- @buses.each_value do |b|
849
- while (m = b.message_queue.message_from_buffer_nonblock)
850
- b.process(m)
851
- end
852
- end
853
- while !@quitting && !@buses.empty?
854
- ready = IO.select(@buses.keys, [], [], 5) # timeout 5 seconds
855
- next unless ready # timeout exceeds so continue unless quitting
856
-
857
- ready.first.each do |socket|
858
- b = @buses[socket]
859
- begin
860
- b.message_queue.buffer_from_socket_nonblock
861
- rescue EOFError, SystemCallError
862
- @buses.delete socket # this bus died
863
- next
864
- end
865
- while (m = b.message_queue.message_from_buffer_nonblock)
866
- b.process(m)
867
- end
868
- end
869
- end
870
- end
871
- end
872
620
  end
data/lib/dbus/logger.rb CHANGED
@@ -17,9 +17,10 @@ module DBus
17
17
  # The default one logs to STDERR,
18
18
  # with DEBUG if $DEBUG is set, otherwise INFO.
19
19
  def logger
20
- unless defined? @logger
20
+ if @logger.nil?
21
+ debug = $DEBUG || ENV["RUBY_DBUS_DEBUG"]
21
22
  @logger = Logger.new($stderr)
22
- @logger.level = $DEBUG ? Logger::DEBUG : Logger::INFO
23
+ @logger.level = debug ? Logger::DEBUG : Logger::INFO
23
24
  end
24
25
  @logger
25
26
  end
data/lib/dbus/main.rb ADDED
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is part of the ruby-dbus project
4
+ # Copyright (C) 2007 Arnaud Cornet and Paul van Tilburg
5
+ # Copyright (C) 2023 Martin Vidner
6
+ #
7
+ # This library is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU Lesser General Public
9
+ # License, version 2.1 as published by the Free Software Foundation.
10
+ # See the file "COPYING" for the exact licensing terms.
11
+
12
+ module DBus
13
+ # = Main event loop class.
14
+ #
15
+ # Class that takes care of handling message and signal events
16
+ # asynchronously. *Note:* This is a native implement and therefore does
17
+ # not integrate with a graphical widget set main loop.
18
+ class Main
19
+ # Create a new main event loop.
20
+ def initialize
21
+ @buses = {}
22
+ @quitting = false
23
+ end
24
+
25
+ # Add a _bus_ to the list of buses to watch for events.
26
+ def <<(bus)
27
+ @buses[bus.message_queue.socket] = bus
28
+ end
29
+
30
+ # Quit a running main loop, to be used eg. from a signal handler
31
+ def quit
32
+ @quitting = true
33
+ end
34
+
35
+ # Run the main loop. This is a blocking call!
36
+ def run
37
+ # before blocking, empty the buffers
38
+ # https://bugzilla.novell.com/show_bug.cgi?id=537401
39
+ @buses.each_value do |b|
40
+ while (m = b.message_queue.message_from_buffer_nonblock)
41
+ b.process(m)
42
+ end
43
+ end
44
+ while !@quitting && !@buses.empty?
45
+ ready = IO.select(@buses.keys, [], [], 5) # timeout 5 seconds
46
+ next unless ready # timeout exceeds so continue unless quitting
47
+
48
+ ready.first.each do |socket|
49
+ b = @buses[socket]
50
+ begin
51
+ b.message_queue.buffer_from_socket_nonblock
52
+ rescue EOFError, SystemCallError => e
53
+ DBus.logger.debug "Got #{e.inspect} from #{socket.inspect}"
54
+ @buses.delete socket # this bus died
55
+ next
56
+ end
57
+ while (m = b.message_queue.message_from_buffer_nonblock)
58
+ b.process(m)
59
+ end
60
+ end
61
+ end
62
+ DBus.logger.debug "Main loop quit" if @quitting
63
+ DBus.logger.debug "Main loop quit, no connections left" if @buses.empty?
64
+ end
65
+ end
66
+ end
data/lib/dbus/message.rb CHANGED
@@ -16,12 +16,6 @@ require_relative "raw_message"
16
16
  #
17
17
  # Module containing all the D-Bus modules and classes.
18
18
  module DBus
19
- # = InvalidDestinationName class
20
- # Thrown when you try to send a message to /org/freedesktop/DBus/Local, that
21
- # is reserved.
22
- class InvalidDestinationName < Exception
23
- end
24
-
25
19
  # = D-Bus message class
26
20
  #
27
21
  # Class that holds any type of message that travels over the bus.
@@ -164,11 +158,15 @@ module DBus
164
158
  SENDER = 7
165
159
  SIGNATURE = 8
166
160
 
161
+ RESERVED_PATH = "/org/freedesktop/DBus/Local"
162
+
167
163
  # Marshall the message with its current set parameters and return
168
164
  # it in a packet form.
165
+ # @return [String]
169
166
  def marshall
170
- if @path == "/org/freedesktop/DBus/Local"
171
- raise InvalidDestinationName
167
+ if @path == RESERVED_PATH
168
+ # the bus would disconnect us, better explain why
169
+ raise "Cannot send a message with the reserved path #{RESERVED_PATH}: #{inspect}"
172
170
  end
173
171
 
174
172
  params_marshaller = PacketMarshaller.new(endianness: ENDIANNESS)