conn.go 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996
  1. package dbus
  2. import (
  3. "context"
  4. "errors"
  5. "io"
  6. "os"
  7. "strings"
  8. "sync"
  9. )
  10. var (
  11. systemBus *Conn
  12. systemBusLck sync.Mutex
  13. sessionBus *Conn
  14. sessionBusLck sync.Mutex
  15. )
  16. // ErrClosed is the error returned by calls on a closed connection.
  17. var ErrClosed = errors.New("dbus: connection closed by user")
  18. // Conn represents a connection to a message bus (usually, the system or
  19. // session bus).
  20. //
  21. // Connections are either shared or private. Shared connections
  22. // are shared between calls to the functions that return them. As a result,
  23. // the methods Close, Auth and Hello must not be called on them.
  24. //
  25. // Multiple goroutines may invoke methods on a connection simultaneously.
  26. type Conn struct {
  27. transport
  28. ctx context.Context
  29. cancelCtx context.CancelFunc
  30. closeOnce sync.Once
  31. closeErr error
  32. busObj BusObject
  33. unixFD bool
  34. uuid string
  35. handler Handler
  36. signalHandler SignalHandler
  37. serialGen SerialGenerator
  38. inInt Interceptor
  39. outInt Interceptor
  40. auth []Auth
  41. names *nameTracker
  42. calls *callTracker
  43. outHandler *outputHandler
  44. eavesdropped chan<- *Message
  45. eavesdroppedLck sync.Mutex
  46. }
  47. // SessionBus returns a shared connection to the session bus, connecting to it
  48. // if not already done.
  49. func SessionBus() (conn *Conn, err error) {
  50. sessionBusLck.Lock()
  51. defer sessionBusLck.Unlock()
  52. if sessionBus != nil &&
  53. sessionBus.Connected() {
  54. return sessionBus, nil
  55. }
  56. defer func() {
  57. if conn != nil {
  58. sessionBus = conn
  59. }
  60. }()
  61. conn, err = ConnectSessionBus()
  62. return
  63. }
  64. func getSessionBusAddress(autolaunch bool) (string, error) {
  65. if address := os.Getenv("DBUS_SESSION_BUS_ADDRESS"); address != "" && address != "autolaunch:" {
  66. return address, nil
  67. } else if address := tryDiscoverDbusSessionBusAddress(); address != "" {
  68. os.Setenv("DBUS_SESSION_BUS_ADDRESS", address)
  69. return address, nil
  70. }
  71. if !autolaunch {
  72. return "", errors.New("dbus: couldn't determine address of session bus")
  73. }
  74. return getSessionBusPlatformAddress()
  75. }
  76. // SessionBusPrivate returns a new private connection to the session bus.
  77. func SessionBusPrivate(opts ...ConnOption) (*Conn, error) {
  78. address, err := getSessionBusAddress(true)
  79. if err != nil {
  80. return nil, err
  81. }
  82. return Dial(address, opts...)
  83. }
  84. // SessionBusPrivate returns a new private connection to the session bus. If
  85. // the session bus is not already open, do not attempt to launch it.
  86. func SessionBusPrivateNoAutoStartup(opts ...ConnOption) (*Conn, error) {
  87. address, err := getSessionBusAddress(false)
  88. if err != nil {
  89. return nil, err
  90. }
  91. return Dial(address, opts...)
  92. }
  93. // SessionBusPrivate returns a new private connection to the session bus.
  94. //
  95. // Deprecated: use SessionBusPrivate with options instead.
  96. func SessionBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) {
  97. return SessionBusPrivate(WithHandler(handler), WithSignalHandler(signalHandler))
  98. }
  99. // SystemBus returns a shared connection to the system bus, connecting to it if
  100. // not already done.
  101. func SystemBus() (conn *Conn, err error) {
  102. systemBusLck.Lock()
  103. defer systemBusLck.Unlock()
  104. if systemBus != nil &&
  105. systemBus.Connected() {
  106. return systemBus, nil
  107. }
  108. defer func() {
  109. if conn != nil {
  110. systemBus = conn
  111. }
  112. }()
  113. conn, err = ConnectSystemBus()
  114. return
  115. }
  116. // ConnectSessionBus connects to the session bus.
  117. func ConnectSessionBus(opts ...ConnOption) (*Conn, error) {
  118. address, err := getSessionBusAddress(true)
  119. if err != nil {
  120. return nil, err
  121. }
  122. return Connect(address, opts...)
  123. }
  124. // ConnectSystemBus connects to the system bus.
  125. func ConnectSystemBus(opts ...ConnOption) (*Conn, error) {
  126. return Connect(getSystemBusPlatformAddress(), opts...)
  127. }
  128. // Connect connects to the given address.
  129. //
  130. // Returned connection is ready to use and doesn't require calling
  131. // Auth and Hello methods to make it usable.
  132. func Connect(address string, opts ...ConnOption) (*Conn, error) {
  133. conn, err := Dial(address, opts...)
  134. if err != nil {
  135. return nil, err
  136. }
  137. if err = conn.Auth(conn.auth); err != nil {
  138. _ = conn.Close()
  139. return nil, err
  140. }
  141. if err = conn.Hello(); err != nil {
  142. _ = conn.Close()
  143. return nil, err
  144. }
  145. return conn, nil
  146. }
  147. // SystemBusPrivate returns a new private connection to the system bus.
  148. // Note: this connection is not ready to use. One must perform Auth and Hello
  149. // on the connection before it is usable.
  150. func SystemBusPrivate(opts ...ConnOption) (*Conn, error) {
  151. return Dial(getSystemBusPlatformAddress(), opts...)
  152. }
  153. // SystemBusPrivateHandler returns a new private connection to the system bus, using the provided handlers.
  154. //
  155. // Deprecated: use SystemBusPrivate with options instead.
  156. func SystemBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) {
  157. return SystemBusPrivate(WithHandler(handler), WithSignalHandler(signalHandler))
  158. }
  159. // Dial establishes a new private connection to the message bus specified by address.
  160. func Dial(address string, opts ...ConnOption) (*Conn, error) {
  161. tr, err := getTransport(address)
  162. if err != nil {
  163. return nil, err
  164. }
  165. return newConn(tr, opts...)
  166. }
  167. // DialHandler establishes a new private connection to the message bus specified by address, using the supplied handlers.
  168. //
  169. // Deprecated: use Dial with options instead.
  170. func DialHandler(address string, handler Handler, signalHandler SignalHandler) (*Conn, error) {
  171. return Dial(address, WithHandler(handler), WithSignalHandler(signalHandler))
  172. }
  173. // ConnOption is a connection option.
  174. type ConnOption func(conn *Conn) error
  175. // WithHandler overrides the default handler.
  176. func WithHandler(handler Handler) ConnOption {
  177. return func(conn *Conn) error {
  178. conn.handler = handler
  179. return nil
  180. }
  181. }
  182. // WithSignalHandler overrides the default signal handler.
  183. func WithSignalHandler(handler SignalHandler) ConnOption {
  184. return func(conn *Conn) error {
  185. conn.signalHandler = handler
  186. return nil
  187. }
  188. }
  189. // WithSerialGenerator overrides the default signals generator.
  190. func WithSerialGenerator(gen SerialGenerator) ConnOption {
  191. return func(conn *Conn) error {
  192. conn.serialGen = gen
  193. return nil
  194. }
  195. }
  196. // WithAuth sets authentication methods for the auth conversation.
  197. func WithAuth(methods ...Auth) ConnOption {
  198. return func(conn *Conn) error {
  199. conn.auth = methods
  200. return nil
  201. }
  202. }
  203. // Interceptor intercepts incoming and outgoing messages.
  204. type Interceptor func(msg *Message)
  205. // WithIncomingInterceptor sets the given interceptor for incoming messages.
  206. func WithIncomingInterceptor(interceptor Interceptor) ConnOption {
  207. return func(conn *Conn) error {
  208. conn.inInt = interceptor
  209. return nil
  210. }
  211. }
  212. // WithOutgoingInterceptor sets the given interceptor for outgoing messages.
  213. func WithOutgoingInterceptor(interceptor Interceptor) ConnOption {
  214. return func(conn *Conn) error {
  215. conn.outInt = interceptor
  216. return nil
  217. }
  218. }
  219. // WithContext overrides the default context for the connection.
  220. func WithContext(ctx context.Context) ConnOption {
  221. return func(conn *Conn) error {
  222. conn.ctx = ctx
  223. return nil
  224. }
  225. }
  226. // NewConn creates a new private *Conn from an already established connection.
  227. func NewConn(conn io.ReadWriteCloser, opts ...ConnOption) (*Conn, error) {
  228. return newConn(genericTransport{conn}, opts...)
  229. }
  230. // NewConnHandler creates a new private *Conn from an already established connection, using the supplied handlers.
  231. //
  232. // Deprecated: use NewConn with options instead.
  233. func NewConnHandler(conn io.ReadWriteCloser, handler Handler, signalHandler SignalHandler) (*Conn, error) {
  234. return NewConn(genericTransport{conn}, WithHandler(handler), WithSignalHandler(signalHandler))
  235. }
  236. // newConn creates a new *Conn from a transport.
  237. func newConn(tr transport, opts ...ConnOption) (*Conn, error) {
  238. conn := new(Conn)
  239. conn.transport = tr
  240. for _, opt := range opts {
  241. if err := opt(conn); err != nil {
  242. return nil, err
  243. }
  244. }
  245. if conn.ctx == nil {
  246. conn.ctx = context.Background()
  247. }
  248. conn.ctx, conn.cancelCtx = context.WithCancel(conn.ctx)
  249. conn.calls = newCallTracker()
  250. if conn.handler == nil {
  251. conn.handler = NewDefaultHandler()
  252. }
  253. if conn.signalHandler == nil {
  254. conn.signalHandler = NewDefaultSignalHandler()
  255. }
  256. if conn.serialGen == nil {
  257. conn.serialGen = newSerialGenerator()
  258. }
  259. conn.outHandler = &outputHandler{conn: conn}
  260. conn.names = newNameTracker()
  261. conn.busObj = conn.Object("org.freedesktop.DBus", "/org/freedesktop/DBus")
  262. go func() {
  263. <-conn.ctx.Done()
  264. conn.Close()
  265. }()
  266. return conn, nil
  267. }
  268. // BusObject returns the object owned by the bus daemon which handles
  269. // administrative requests.
  270. func (conn *Conn) BusObject() BusObject {
  271. return conn.busObj
  272. }
  273. // Close closes the connection. Any blocked operations will return with errors
  274. // and the channels passed to Eavesdrop and Signal are closed. This method must
  275. // not be called on shared connections.
  276. func (conn *Conn) Close() error {
  277. conn.closeOnce.Do(func() {
  278. conn.outHandler.close()
  279. if term, ok := conn.signalHandler.(Terminator); ok {
  280. term.Terminate()
  281. }
  282. if term, ok := conn.handler.(Terminator); ok {
  283. term.Terminate()
  284. }
  285. conn.eavesdroppedLck.Lock()
  286. if conn.eavesdropped != nil {
  287. close(conn.eavesdropped)
  288. }
  289. conn.eavesdroppedLck.Unlock()
  290. conn.cancelCtx()
  291. conn.closeErr = conn.transport.Close()
  292. })
  293. return conn.closeErr
  294. }
  295. // Context returns the context associated with the connection. The
  296. // context will be cancelled when the connection is closed.
  297. func (conn *Conn) Context() context.Context {
  298. return conn.ctx
  299. }
  300. // Connected returns whether conn is connected
  301. func (conn *Conn) Connected() bool {
  302. return conn.ctx.Err() == nil
  303. }
  304. // Eavesdrop causes conn to send all incoming messages to the given channel
  305. // without further processing. Method replies, errors and signals will not be
  306. // sent to the appropriate channels and method calls will not be handled. If nil
  307. // is passed, the normal behaviour is restored.
  308. //
  309. // The caller has to make sure that ch is sufficiently buffered;
  310. // if a message arrives when a write to ch is not possible, the message is
  311. // discarded.
  312. func (conn *Conn) Eavesdrop(ch chan<- *Message) {
  313. conn.eavesdroppedLck.Lock()
  314. conn.eavesdropped = ch
  315. conn.eavesdroppedLck.Unlock()
  316. }
  317. // getSerial returns an unused serial.
  318. func (conn *Conn) getSerial() uint32 {
  319. return conn.serialGen.GetSerial()
  320. }
  321. // Hello sends the initial org.freedesktop.DBus.Hello call. This method must be
  322. // called after authentication, but before sending any other messages to the
  323. // bus. Hello must not be called for shared connections.
  324. func (conn *Conn) Hello() error {
  325. var s string
  326. err := conn.busObj.Call("org.freedesktop.DBus.Hello", 0).Store(&s)
  327. if err != nil {
  328. return err
  329. }
  330. conn.names.acquireUniqueConnectionName(s)
  331. return nil
  332. }
  333. // inWorker runs in an own goroutine, reading incoming messages from the
  334. // transport and dispatching them appropriately.
  335. func (conn *Conn) inWorker() {
  336. sequenceGen := newSequenceGenerator()
  337. for {
  338. msg, err := conn.ReadMessage()
  339. if err != nil {
  340. if _, ok := err.(InvalidMessageError); !ok {
  341. // Some read error occurred (usually EOF); we can't really do
  342. // anything but to shut down all stuff and returns errors to all
  343. // pending replies.
  344. conn.Close()
  345. conn.calls.finalizeAllWithError(sequenceGen, err)
  346. return
  347. }
  348. // invalid messages are ignored
  349. continue
  350. }
  351. conn.eavesdroppedLck.Lock()
  352. if conn.eavesdropped != nil {
  353. select {
  354. case conn.eavesdropped <- msg:
  355. default:
  356. }
  357. conn.eavesdroppedLck.Unlock()
  358. continue
  359. }
  360. conn.eavesdroppedLck.Unlock()
  361. dest, _ := msg.Headers[FieldDestination].value.(string)
  362. found := dest == "" ||
  363. !conn.names.uniqueNameIsKnown() ||
  364. conn.names.isKnownName(dest)
  365. if !found {
  366. // Eavesdropped a message, but no channel for it is registered.
  367. // Ignore it.
  368. continue
  369. }
  370. if conn.inInt != nil {
  371. conn.inInt(msg)
  372. }
  373. sequence := sequenceGen.next()
  374. switch msg.Type {
  375. case TypeError:
  376. conn.serialGen.RetireSerial(conn.calls.handleDBusError(sequence, msg))
  377. case TypeMethodReply:
  378. conn.serialGen.RetireSerial(conn.calls.handleReply(sequence, msg))
  379. case TypeSignal:
  380. conn.handleSignal(sequence, msg)
  381. case TypeMethodCall:
  382. go conn.handleCall(msg)
  383. }
  384. }
  385. }
  386. func (conn *Conn) handleSignal(sequence Sequence, msg *Message) {
  387. iface := msg.Headers[FieldInterface].value.(string)
  388. member := msg.Headers[FieldMember].value.(string)
  389. // as per http://dbus.freedesktop.org/doc/dbus-specification.html ,
  390. // sender is optional for signals.
  391. sender, _ := msg.Headers[FieldSender].value.(string)
  392. if iface == "org.freedesktop.DBus" && sender == "org.freedesktop.DBus" {
  393. if member == "NameLost" {
  394. // If we lost the name on the bus, remove it from our
  395. // tracking list.
  396. name, ok := msg.Body[0].(string)
  397. if !ok {
  398. panic("Unable to read the lost name")
  399. }
  400. conn.names.loseName(name)
  401. } else if member == "NameAcquired" {
  402. // If we acquired the name on the bus, add it to our
  403. // tracking list.
  404. name, ok := msg.Body[0].(string)
  405. if !ok {
  406. panic("Unable to read the acquired name")
  407. }
  408. conn.names.acquireName(name)
  409. }
  410. }
  411. signal := &Signal{
  412. Sender: sender,
  413. Path: msg.Headers[FieldPath].value.(ObjectPath),
  414. Name: iface + "." + member,
  415. Body: msg.Body,
  416. Sequence: sequence,
  417. }
  418. conn.signalHandler.DeliverSignal(iface, member, signal)
  419. }
  420. // Names returns the list of all names that are currently owned by this
  421. // connection. The slice is always at least one element long, the first element
  422. // being the unique name of the connection.
  423. func (conn *Conn) Names() []string {
  424. return conn.names.listKnownNames()
  425. }
  426. // Object returns the object identified by the given destination name and path.
  427. func (conn *Conn) Object(dest string, path ObjectPath) BusObject {
  428. return &Object{conn, dest, path}
  429. }
  430. func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) {
  431. if msg.serial == 0 {
  432. msg.serial = conn.getSerial()
  433. }
  434. if conn.outInt != nil {
  435. conn.outInt(msg)
  436. }
  437. err := conn.outHandler.sendAndIfClosed(msg, ifClosed)
  438. if err != nil {
  439. conn.handleSendError(msg, err)
  440. } else if msg.Type != TypeMethodCall {
  441. conn.serialGen.RetireSerial(msg.serial)
  442. }
  443. }
  444. func (conn *Conn) handleSendError(msg *Message, err error) {
  445. if msg.Type == TypeMethodCall {
  446. conn.calls.handleSendError(msg, err)
  447. } else if msg.Type == TypeMethodReply {
  448. if _, ok := err.(FormatError); ok {
  449. conn.sendError(err, msg.Headers[FieldDestination].value.(string), msg.Headers[FieldReplySerial].value.(uint32))
  450. }
  451. }
  452. conn.serialGen.RetireSerial(msg.serial)
  453. }
  454. // Send sends the given message to the message bus. You usually don't need to
  455. // use this; use the higher-level equivalents (Call / Go, Emit and Export)
  456. // instead. If msg is a method call and NoReplyExpected is not set, a non-nil
  457. // call is returned and the same value is sent to ch (which must be buffered)
  458. // once the call is complete. Otherwise, ch is ignored and a Call structure is
  459. // returned of which only the Err member is valid.
  460. func (conn *Conn) Send(msg *Message, ch chan *Call) *Call {
  461. return conn.send(context.Background(), msg, ch)
  462. }
  463. // SendWithContext acts like Send but takes a context
  464. func (conn *Conn) SendWithContext(ctx context.Context, msg *Message, ch chan *Call) *Call {
  465. return conn.send(ctx, msg, ch)
  466. }
  467. func (conn *Conn) send(ctx context.Context, msg *Message, ch chan *Call) *Call {
  468. if ctx == nil {
  469. panic("nil context")
  470. }
  471. if ch == nil {
  472. ch = make(chan *Call, 1)
  473. } else if cap(ch) == 0 {
  474. panic("dbus: unbuffered channel passed to (*Conn).Send")
  475. }
  476. var call *Call
  477. ctx, canceler := context.WithCancel(ctx)
  478. msg.serial = conn.getSerial()
  479. if msg.Type == TypeMethodCall && msg.Flags&FlagNoReplyExpected == 0 {
  480. call = new(Call)
  481. call.Destination, _ = msg.Headers[FieldDestination].value.(string)
  482. call.Path, _ = msg.Headers[FieldPath].value.(ObjectPath)
  483. iface, _ := msg.Headers[FieldInterface].value.(string)
  484. member, _ := msg.Headers[FieldMember].value.(string)
  485. call.Method = iface + "." + member
  486. call.Args = msg.Body
  487. call.Done = ch
  488. call.ctx = ctx
  489. call.ctxCanceler = canceler
  490. conn.calls.track(msg.serial, call)
  491. if ctx.Err() != nil {
  492. // short path: don't even send the message if context already cancelled
  493. conn.calls.handleSendError(msg, ctx.Err())
  494. return call
  495. }
  496. go func() {
  497. <-ctx.Done()
  498. conn.calls.handleSendError(msg, ctx.Err())
  499. }()
  500. conn.sendMessageAndIfClosed(msg, func() {
  501. conn.calls.handleSendError(msg, ErrClosed)
  502. canceler()
  503. })
  504. } else {
  505. canceler()
  506. call = &Call{Err: nil, Done: ch}
  507. ch <- call
  508. conn.sendMessageAndIfClosed(msg, func() {
  509. call = &Call{Err: ErrClosed}
  510. })
  511. }
  512. return call
  513. }
  514. // sendError creates an error message corresponding to the parameters and sends
  515. // it to conn.out.
  516. func (conn *Conn) sendError(err error, dest string, serial uint32) {
  517. var e *Error
  518. switch em := err.(type) {
  519. case Error:
  520. e = &em
  521. case *Error:
  522. e = em
  523. case DBusError:
  524. name, body := em.DBusError()
  525. e = NewError(name, body)
  526. default:
  527. e = MakeFailedError(err)
  528. }
  529. msg := new(Message)
  530. msg.Type = TypeError
  531. msg.Headers = make(map[HeaderField]Variant)
  532. if dest != "" {
  533. msg.Headers[FieldDestination] = MakeVariant(dest)
  534. }
  535. msg.Headers[FieldErrorName] = MakeVariant(e.Name)
  536. msg.Headers[FieldReplySerial] = MakeVariant(serial)
  537. msg.Body = e.Body
  538. if len(e.Body) > 0 {
  539. msg.Headers[FieldSignature] = MakeVariant(SignatureOf(e.Body...))
  540. }
  541. conn.sendMessageAndIfClosed(msg, nil)
  542. }
  543. // sendReply creates a method reply message corresponding to the parameters and
  544. // sends it to conn.out.
  545. func (conn *Conn) sendReply(dest string, serial uint32, values ...interface{}) {
  546. msg := new(Message)
  547. msg.Type = TypeMethodReply
  548. msg.Headers = make(map[HeaderField]Variant)
  549. if dest != "" {
  550. msg.Headers[FieldDestination] = MakeVariant(dest)
  551. }
  552. msg.Headers[FieldReplySerial] = MakeVariant(serial)
  553. msg.Body = values
  554. if len(values) > 0 {
  555. msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...))
  556. }
  557. conn.sendMessageAndIfClosed(msg, nil)
  558. }
  559. // AddMatchSignal registers the given match rule to receive broadcast
  560. // signals based on their contents.
  561. func (conn *Conn) AddMatchSignal(options ...MatchOption) error {
  562. return conn.AddMatchSignalContext(context.Background(), options...)
  563. }
  564. // AddMatchSignalContext acts like AddMatchSignal but takes a context.
  565. func (conn *Conn) AddMatchSignalContext(ctx context.Context, options ...MatchOption) error {
  566. options = append([]MatchOption{withMatchType("signal")}, options...)
  567. return conn.busObj.CallWithContext(
  568. ctx,
  569. "org.freedesktop.DBus.AddMatch", 0,
  570. formatMatchOptions(options),
  571. ).Store()
  572. }
  573. // RemoveMatchSignal removes the first rule that matches previously registered with AddMatchSignal.
  574. func (conn *Conn) RemoveMatchSignal(options ...MatchOption) error {
  575. return conn.RemoveMatchSignalContext(context.Background(), options...)
  576. }
  577. // RemoveMatchSignalContext acts like RemoveMatchSignal but takes a context.
  578. func (conn *Conn) RemoveMatchSignalContext(ctx context.Context, options ...MatchOption) error {
  579. options = append([]MatchOption{withMatchType("signal")}, options...)
  580. return conn.busObj.CallWithContext(
  581. ctx,
  582. "org.freedesktop.DBus.RemoveMatch", 0,
  583. formatMatchOptions(options),
  584. ).Store()
  585. }
  586. // Signal registers the given channel to be passed all received signal messages.
  587. //
  588. // Multiple of these channels can be registered at the same time. The channel is
  589. // closed if the Conn is closed; it should not be closed by the caller before
  590. // RemoveSignal was called on it.
  591. //
  592. // These channels are "overwritten" by Eavesdrop; i.e., if there currently is a
  593. // channel for eavesdropped messages, this channel receives all signals, and
  594. // none of the channels passed to Signal will receive any signals.
  595. //
  596. // Panics if the signal handler is not a `SignalRegistrar`.
  597. func (conn *Conn) Signal(ch chan<- *Signal) {
  598. handler, ok := conn.signalHandler.(SignalRegistrar)
  599. if !ok {
  600. panic("cannot use this method with a non SignalRegistrar handler")
  601. }
  602. handler.AddSignal(ch)
  603. }
  604. // RemoveSignal removes the given channel from the list of the registered channels.
  605. //
  606. // Panics if the signal handler is not a `SignalRegistrar`.
  607. func (conn *Conn) RemoveSignal(ch chan<- *Signal) {
  608. handler, ok := conn.signalHandler.(SignalRegistrar)
  609. if !ok {
  610. panic("cannot use this method with a non SignalRegistrar handler")
  611. }
  612. handler.RemoveSignal(ch)
  613. }
  614. // SupportsUnixFDs returns whether the underlying transport supports passing of
  615. // unix file descriptors. If this is false, method calls containing unix file
  616. // descriptors will return an error and emitted signals containing them will
  617. // not be sent.
  618. func (conn *Conn) SupportsUnixFDs() bool {
  619. return conn.unixFD
  620. }
  621. // Error represents a D-Bus message of type Error.
  622. type Error struct {
  623. Name string
  624. Body []interface{}
  625. }
  626. func NewError(name string, body []interface{}) *Error {
  627. return &Error{name, body}
  628. }
  629. func (e Error) Error() string {
  630. if len(e.Body) >= 1 {
  631. s, ok := e.Body[0].(string)
  632. if ok {
  633. return s
  634. }
  635. }
  636. return e.Name
  637. }
  638. // Signal represents a D-Bus message of type Signal. The name member is given in
  639. // "interface.member" notation, e.g. org.freedesktop.D-Bus.NameLost.
  640. type Signal struct {
  641. Sender string
  642. Path ObjectPath
  643. Name string
  644. Body []interface{}
  645. Sequence Sequence
  646. }
  647. // transport is a D-Bus transport.
  648. type transport interface {
  649. // Read and Write raw data (for example, for the authentication protocol).
  650. io.ReadWriteCloser
  651. // Send the initial null byte used for the EXTERNAL mechanism.
  652. SendNullByte() error
  653. // Returns whether this transport supports passing Unix FDs.
  654. SupportsUnixFDs() bool
  655. // Signal the transport that Unix FD passing is enabled for this connection.
  656. EnableUnixFDs()
  657. // Read / send a message, handling things like Unix FDs.
  658. ReadMessage() (*Message, error)
  659. SendMessage(*Message) error
  660. }
  661. var (
  662. transports = make(map[string]func(string) (transport, error))
  663. )
  664. func getTransport(address string) (transport, error) {
  665. var err error
  666. var t transport
  667. addresses := strings.Split(address, ";")
  668. for _, v := range addresses {
  669. i := strings.IndexRune(v, ':')
  670. if i == -1 {
  671. err = errors.New("dbus: invalid bus address (no transport)")
  672. continue
  673. }
  674. f := transports[v[:i]]
  675. if f == nil {
  676. err = errors.New("dbus: invalid bus address (invalid or unsupported transport)")
  677. continue
  678. }
  679. t, err = f(v[i+1:])
  680. if err == nil {
  681. return t, nil
  682. }
  683. }
  684. return nil, err
  685. }
  686. // getKey gets a key from a the list of keys. Returns "" on error / not found...
  687. func getKey(s, key string) string {
  688. for _, keyEqualsValue := range strings.Split(s, ",") {
  689. keyValue := strings.SplitN(keyEqualsValue, "=", 2)
  690. if len(keyValue) == 2 && keyValue[0] == key {
  691. val, err := UnescapeBusAddressValue(keyValue[1])
  692. if err != nil {
  693. // No way to return an error.
  694. return ""
  695. }
  696. return val
  697. }
  698. }
  699. return ""
  700. }
  701. type outputHandler struct {
  702. conn *Conn
  703. sendLck sync.Mutex
  704. closed struct {
  705. isClosed bool
  706. lck sync.RWMutex
  707. }
  708. }
  709. func (h *outputHandler) sendAndIfClosed(msg *Message, ifClosed func()) error {
  710. h.closed.lck.RLock()
  711. defer h.closed.lck.RUnlock()
  712. if h.closed.isClosed {
  713. if ifClosed != nil {
  714. ifClosed()
  715. }
  716. return nil
  717. }
  718. h.sendLck.Lock()
  719. defer h.sendLck.Unlock()
  720. return h.conn.SendMessage(msg)
  721. }
  722. func (h *outputHandler) close() {
  723. h.closed.lck.Lock()
  724. defer h.closed.lck.Unlock()
  725. h.closed.isClosed = true
  726. }
  727. type serialGenerator struct {
  728. lck sync.Mutex
  729. nextSerial uint32
  730. serialUsed map[uint32]bool
  731. }
  732. func newSerialGenerator() *serialGenerator {
  733. return &serialGenerator{
  734. serialUsed: map[uint32]bool{0: true},
  735. nextSerial: 1,
  736. }
  737. }
  738. func (gen *serialGenerator) GetSerial() uint32 {
  739. gen.lck.Lock()
  740. defer gen.lck.Unlock()
  741. n := gen.nextSerial
  742. for gen.serialUsed[n] {
  743. n++
  744. }
  745. gen.serialUsed[n] = true
  746. gen.nextSerial = n + 1
  747. return n
  748. }
  749. func (gen *serialGenerator) RetireSerial(serial uint32) {
  750. gen.lck.Lock()
  751. defer gen.lck.Unlock()
  752. delete(gen.serialUsed, serial)
  753. }
  754. type nameTracker struct {
  755. lck sync.RWMutex
  756. unique string
  757. names map[string]struct{}
  758. }
  759. func newNameTracker() *nameTracker {
  760. return &nameTracker{names: map[string]struct{}{}}
  761. }
  762. func (tracker *nameTracker) acquireUniqueConnectionName(name string) {
  763. tracker.lck.Lock()
  764. defer tracker.lck.Unlock()
  765. tracker.unique = name
  766. }
  767. func (tracker *nameTracker) acquireName(name string) {
  768. tracker.lck.Lock()
  769. defer tracker.lck.Unlock()
  770. tracker.names[name] = struct{}{}
  771. }
  772. func (tracker *nameTracker) loseName(name string) {
  773. tracker.lck.Lock()
  774. defer tracker.lck.Unlock()
  775. delete(tracker.names, name)
  776. }
  777. func (tracker *nameTracker) uniqueNameIsKnown() bool {
  778. tracker.lck.RLock()
  779. defer tracker.lck.RUnlock()
  780. return tracker.unique != ""
  781. }
  782. func (tracker *nameTracker) isKnownName(name string) bool {
  783. tracker.lck.RLock()
  784. defer tracker.lck.RUnlock()
  785. _, ok := tracker.names[name]
  786. return ok || name == tracker.unique
  787. }
  788. func (tracker *nameTracker) listKnownNames() []string {
  789. tracker.lck.RLock()
  790. defer tracker.lck.RUnlock()
  791. out := make([]string, 0, len(tracker.names)+1)
  792. out = append(out, tracker.unique)
  793. for k := range tracker.names {
  794. out = append(out, k)
  795. }
  796. return out
  797. }
  798. type callTracker struct {
  799. calls map[uint32]*Call
  800. lck sync.RWMutex
  801. }
  802. func newCallTracker() *callTracker {
  803. return &callTracker{calls: map[uint32]*Call{}}
  804. }
  805. func (tracker *callTracker) track(sn uint32, call *Call) {
  806. tracker.lck.Lock()
  807. tracker.calls[sn] = call
  808. tracker.lck.Unlock()
  809. }
  810. func (tracker *callTracker) handleReply(sequence Sequence, msg *Message) uint32 {
  811. serial := msg.Headers[FieldReplySerial].value.(uint32)
  812. tracker.lck.RLock()
  813. _, ok := tracker.calls[serial]
  814. tracker.lck.RUnlock()
  815. if ok {
  816. tracker.finalizeWithBody(serial, sequence, msg.Body)
  817. }
  818. return serial
  819. }
  820. func (tracker *callTracker) handleDBusError(sequence Sequence, msg *Message) uint32 {
  821. serial := msg.Headers[FieldReplySerial].value.(uint32)
  822. tracker.lck.RLock()
  823. _, ok := tracker.calls[serial]
  824. tracker.lck.RUnlock()
  825. if ok {
  826. name, _ := msg.Headers[FieldErrorName].value.(string)
  827. tracker.finalizeWithError(serial, sequence, Error{name, msg.Body})
  828. }
  829. return serial
  830. }
  831. func (tracker *callTracker) handleSendError(msg *Message, err error) {
  832. if err == nil {
  833. return
  834. }
  835. tracker.lck.RLock()
  836. _, ok := tracker.calls[msg.serial]
  837. tracker.lck.RUnlock()
  838. if ok {
  839. tracker.finalizeWithError(msg.serial, NoSequence, err)
  840. }
  841. }
  842. // finalize was the only func that did not strobe Done
  843. func (tracker *callTracker) finalize(sn uint32) {
  844. tracker.lck.Lock()
  845. defer tracker.lck.Unlock()
  846. c, ok := tracker.calls[sn]
  847. if ok {
  848. delete(tracker.calls, sn)
  849. c.ContextCancel()
  850. }
  851. }
  852. func (tracker *callTracker) finalizeWithBody(sn uint32, sequence Sequence, body []interface{}) {
  853. tracker.lck.Lock()
  854. c, ok := tracker.calls[sn]
  855. if ok {
  856. delete(tracker.calls, sn)
  857. }
  858. tracker.lck.Unlock()
  859. if ok {
  860. c.Body = body
  861. c.ResponseSequence = sequence
  862. c.done()
  863. }
  864. }
  865. func (tracker *callTracker) finalizeWithError(sn uint32, sequence Sequence, err error) {
  866. tracker.lck.Lock()
  867. c, ok := tracker.calls[sn]
  868. if ok {
  869. delete(tracker.calls, sn)
  870. }
  871. tracker.lck.Unlock()
  872. if ok {
  873. c.Err = err
  874. c.ResponseSequence = sequence
  875. c.done()
  876. }
  877. }
  878. func (tracker *callTracker) finalizeAllWithError(sequenceGen *sequenceGenerator, err error) {
  879. tracker.lck.Lock()
  880. closedCalls := make([]*Call, 0, len(tracker.calls))
  881. for sn := range tracker.calls {
  882. closedCalls = append(closedCalls, tracker.calls[sn])
  883. }
  884. tracker.calls = map[uint32]*Call{}
  885. tracker.lck.Unlock()
  886. for _, call := range closedCalls {
  887. call.Err = err
  888. call.ResponseSequence = sequenceGen.next()
  889. call.done()
  890. }
  891. }