ruby-dbus 0.22.1 → 0.23.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 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)