dbus.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. //go:build linux && !android && !ts_omit_dbus
  4. package dns
  5. import (
  6. "context"
  7. "time"
  8. "github.com/godbus/dbus/v5"
  9. )
  10. func init() {
  11. optDBusPing.Set(dbusPing)
  12. optDBusReadString.Set(dbusReadString)
  13. }
  14. func dbusPing(name, objectPath string) error {
  15. conn, err := dbus.SystemBus()
  16. if err != nil {
  17. // DBus probably not running.
  18. return err
  19. }
  20. ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  21. defer cancel()
  22. obj := conn.Object(name, dbus.ObjectPath(objectPath))
  23. call := obj.CallWithContext(ctx, "org.freedesktop.DBus.Peer.Ping", 0)
  24. return call.Err
  25. }
  26. // dbusReadString reads a string property from the provided name and object
  27. // path. property must be in "interface.member" notation.
  28. func dbusReadString(name, objectPath, iface, member string) (string, error) {
  29. conn, err := dbus.SystemBus()
  30. if err != nil {
  31. // DBus probably not running.
  32. return "", err
  33. }
  34. ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  35. defer cancel()
  36. obj := conn.Object(name, dbus.ObjectPath(objectPath))
  37. var result dbus.Variant
  38. err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, iface, member).Store(&result)
  39. if err != nil {
  40. return "", err
  41. }
  42. if s, ok := result.Value().(string); ok {
  43. return s, nil
  44. }
  45. return result.String(), nil
  46. }