go.mod: godbus/dbus/v5 v5.0.3, coreos/go-systemd v22.2.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2021-03-12 17:08:11 +01:00
parent d2d89ddfad
commit bc856372bb
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
57 changed files with 918 additions and 305 deletions

4
go.mod
View File

@ -9,12 +9,12 @@ require (
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44 github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44
github.com/containernetworking/cni v0.8.1-0.20201216164644-62e54113f44a github.com/containernetworking/cni v0.8.1-0.20201216164644-62e54113f44a
github.com/coreos/go-iptables v0.5.0 github.com/coreos/go-iptables v0.5.0
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 github.com/coreos/go-systemd/v22 v22.2.0
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c
github.com/d2g/dhcp4client v1.0.0 github.com/d2g/dhcp4client v1.0.0
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5 github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5
github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4 // indirect github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4 // indirect
github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c github.com/godbus/dbus/v5 v5.0.3
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56 github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56
github.com/mattn/go-shellwords v1.0.11 github.com/mattn/go-shellwords v1.0.11
github.com/onsi/ginkgo v1.13.0 github.com/onsi/ginkgo v1.13.0

8
go.sum
View File

@ -10,8 +10,8 @@ github.com/containernetworking/cni v0.8.1-0.20201216164644-62e54113f44a h1:EDko/
github.com/containernetworking/cni v0.8.1-0.20201216164644-62e54113f44a/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y= github.com/containernetworking/cni v0.8.1-0.20201216164644-62e54113f44a/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y=
github.com/coreos/go-iptables v0.5.0 h1:mw6SAibtHKZcNzAsOxjoHIG0gy5YFHhypWSSNc6EjbQ= github.com/coreos/go-iptables v0.5.0 h1:mw6SAibtHKZcNzAsOxjoHIG0gy5YFHhypWSSNc6EjbQ=
github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 h1:u9SHYsPQNyt5tgDm3YN7+9dYrpK96E5wFilTFWIDZOM= github.com/coreos/go-systemd/v22 v22.2.0 h1:BBmbNtSc5PuUM3Byxs7yE5rLdxQO4/FMoEXY5Rle4GA=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.2.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c h1:Xo2rK1pzOm0jO6abTPIQwbAmqBIOj132otexc1mmzFc= github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c h1:Xo2rK1pzOm0jO6abTPIQwbAmqBIOj132otexc1mmzFc=
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
github.com/d2g/dhcp4client v1.0.0 h1:suYBsYZIkSlUMEz4TAYCczKf62IA2UWC+O8+KtdOhCo= github.com/d2g/dhcp4client v1.0.0 h1:suYBsYZIkSlUMEz4TAYCczKf62IA2UWC+O8+KtdOhCo=
@ -28,8 +28,8 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c h1:RBUpb2b14UnmRHNd2uHz20ZHLDK+SW5Us/vWF5IHRaY= github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME=
github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=

View File

@ -31,7 +31,7 @@ import (
"github.com/containernetworking/cni/pkg/skel" "github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types" "github.com/containernetworking/cni/pkg/types"
current "github.com/containernetworking/cni/pkg/types/100" current "github.com/containernetworking/cni/pkg/types/100"
"github.com/coreos/go-systemd/activation" "github.com/coreos/go-systemd/v22/activation"
) )
const listenFdsStart = 3 const listenFdsStart = 3

View File

@ -28,7 +28,7 @@ import (
"github.com/containernetworking/plugins/pkg/ns" "github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils" "github.com/containernetworking/plugins/pkg/testutils"
"github.com/godbus/dbus" "github.com/godbus/dbus/v5"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"

View File

@ -19,7 +19,7 @@ import (
"strings" "strings"
current "github.com/containernetworking/cni/pkg/types/100" current "github.com/containernetworking/cni/pkg/types/100"
"github.com/godbus/dbus" "github.com/godbus/dbus/v5"
) )
const ( const (

View File

@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// +build !windows
// Package activation implements primitives for systemd socket activation. // Package activation implements primitives for systemd socket activation.
package activation package activation

View File

@ -0,0 +1,21 @@
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package activation
import "os"
func Files(unsetEnv bool) []*os.File {
return nil
}

View File

@ -67,7 +67,7 @@ func TLSListeners(tlsConfig *tls.Config) ([]net.Listener, error) {
return nil, err return nil, err
} }
if tlsConfig != nil && err == nil { if tlsConfig != nil {
for i, l := range listeners { for i, l := range listeners {
// Activate TLS only for TCP sockets // Activate TLS only for TCP sockets
if l.Addr().Network() == "tcp" { if l.Addr().Network() == "tcp" {
@ -88,7 +88,7 @@ func TLSListenersWithNames(tlsConfig *tls.Config) (map[string][]net.Listener, er
return nil, err return nil, err
} }
if tlsConfig != nil && err == nil { if tlsConfig != nil {
for _, ll := range listeners { for _, ll := range listeners {
// Activate TLS only for TCP sockets // Activate TLS only for TCP sockets
for i, l := range ll { for i, l := range ll {

View File

@ -1,40 +0,0 @@
dist: precise
language: go
go_import_path: github.com/godbus/dbus
sudo: true
go:
- 1.6.3
- 1.7.3
- tip
env:
global:
matrix:
- TARGET=amd64
- TARGET=arm64
- TARGET=arm
- TARGET=386
- TARGET=ppc64le
matrix:
fast_finish: true
allow_failures:
- go: tip
exclude:
- go: tip
env: TARGET=arm
- go: tip
env: TARGET=arm64
- go: tip
env: TARGET=386
- go: tip
env: TARGET=ppc64le
addons:
apt:
packages:
- dbus
- dbus-x11
before_install:

View File

@ -1,42 +0,0 @@
// +build !darwin
package dbus
import (
"bytes"
"errors"
"fmt"
"os"
"os/exec"
)
const defaultSystemBusAddress = "unix:path=/var/run/dbus/system_bus_socket"
func getSessionBusPlatformAddress() (string, error) {
cmd := exec.Command("dbus-launch")
b, err := cmd.CombinedOutput()
if err != nil {
return "", err
}
i := bytes.IndexByte(b, '=')
j := bytes.IndexByte(b, '\n')
if i == -1 || j == -1 {
return "", errors.New("dbus: couldn't determine address of session bus")
}
env, addr := string(b[0:i]), string(b[i+1:j])
os.Setenv(env, addr)
return addr, nil
}
func getSystemBusPlatformAddress() string {
address := os.Getenv("DBUS_SYSTEM_BUS_ADDRESS")
if address != "" {
return fmt.Sprintf("unix:path=%s", address)
}
return defaultSystemBusAddress
}

50
vendor/github.com/godbus/dbus/v5/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,50 @@
dist: bionic
language: go
go_import_path: github.com/godbus/dbus
go:
- 1.11.x
- 1.12.x
- 1.13.x
- tip
matrix:
fast_finish: true
allow_failures:
- go: tip
addons:
apt:
packages:
- dbus
- dbus-x11
before_install:
- export GO111MODULE=on
script:
- go test -v -race -mod=readonly ./... # Run all the tests with the race detector enabled
- go vet ./... # go vet is the official Go static analyzer
jobs:
include:
# The build matrix doesn't cover build stages, so manually expand
# the jobs with anchors
- &multiarch
stage: "Multiarch Test"
go: 1.11.x
env: TARGETS="386 arm arm64 ppc64le"
before_install:
- docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
script:
- |
set -e
for target in $TARGETS; do
printf "\e[1mRunning test suite under ${target}.\e[0m\n"
GOARCH="$target" go test -v ./...
printf "\n\n"
done
- <<: *multiarch
go: 1.12.x
- <<: *multiarch
go: 1.13.x

View File

@ -14,7 +14,7 @@ D-Bus message bus system.
### Installation ### Installation
This packages requires Go 1.1. If you installed it and set up your GOPATH, just run: This packages requires Go 1.7. If you installed it and set up your GOPATH, just run:
``` ```
go get github.com/godbus/dbus go get github.com/godbus/dbus

View File

@ -77,7 +77,7 @@ func (conn *Conn) Auth(methods []Auth) error {
for _, m := range methods { for _, m := range methods {
if name, data, status := m.FirstData(); bytes.Equal(v, name) { if name, data, status := m.FirstData(); bytes.Equal(v, name) {
var ok bool var ok bool
err = authWriteLine(conn.transport, []byte("AUTH"), []byte(v), data) err = authWriteLine(conn.transport, []byte("AUTH"), v, data)
if err != nil { if err != nil {
return err return err
} }
@ -127,7 +127,7 @@ func (conn *Conn) Auth(methods []Auth) error {
// tryAuth tries to authenticate with m as the mechanism, using state as the // tryAuth tries to authenticate with m as the mechanism, using state as the
// initial authState and in for reading input. It returns (nil, true) on // initial authState and in for reading input. It returns (nil, true) on
// success, (nil, false) on a REJECTED and (someErr, false) if some other // success, (nil, false) on a REJECTED and (someErr, false) if some other
// error occured. // error occurred.
func (conn *Conn) tryAuth(m Auth, state authState, in *bufio.Reader) (error, bool) { func (conn *Conn) tryAuth(m Auth, state authState, in *bufio.Reader) (error, bool) {
for { for {
s, err := authReadLine(in) s, err := authReadLine(in)

16
vendor/github.com/godbus/dbus/v5/auth_anonymous.go generated vendored Normal file
View File

@ -0,0 +1,16 @@
package dbus
// AuthAnonymous returns an Auth that uses the ANONYMOUS mechanism.
func AuthAnonymous() Auth {
return &authAnonymous{}
}
type authAnonymous struct{}
func (a *authAnonymous) FirstData() (name, resp []byte, status AuthStatus) {
return []byte("ANONYMOUS"), nil, AuthOk
}
func (a *authAnonymous) HandleData(data []byte) (resp []byte, status AuthStatus) {
return nil, AuthError
}

View File

@ -60,7 +60,7 @@ func (a authCookieSha1) HandleData(data []byte) ([]byte, AuthStatus) {
// getCookie searches for the cookie identified by id in context and returns // getCookie searches for the cookie identified by id in context and returns
// the cookie content or nil. (Since HandleData can't return a specific error, // the cookie content or nil. (Since HandleData can't return a specific error,
// but only whether an error occured, this function also doesn't bother to // but only whether an error occurred, this function also doesn't bother to
// return an error.) // return an error.)
func (a authCookieSha1) getCookie(context, id []byte) []byte { func (a authCookieSha1) getCookie(context, id []byte) []byte {
file, err := os.Open(a.home + "/.dbus-keyrings/" + string(context)) file, err := os.Open(a.home + "/.dbus-keyrings/" + string(context))

View File

@ -1,9 +1,12 @@
package dbus package dbus
import ( import (
"context"
"errors" "errors"
) )
var errSignature = errors.New("dbus: mismatched signature")
// Call represents a pending or completed method call. // Call represents a pending or completed method call.
type Call struct { type Call struct {
Destination string Destination string
@ -20,9 +23,25 @@ type Call struct {
// Holds the response once the call is done. // Holds the response once the call is done.
Body []interface{} Body []interface{}
// tracks context and canceler
ctx context.Context
ctxCanceler context.CancelFunc
} }
var errSignature = errors.New("dbus: mismatched signature") func (c *Call) Context() context.Context {
if c.ctx == nil {
return context.Background()
}
return c.ctx
}
func (c *Call) ContextCancel() {
if c.ctxCanceler != nil {
c.ctxCanceler()
}
}
// Store stores the body of the reply into the provided pointers. It returns // Store stores the body of the reply into the provided pointers. It returns
// an error if the signatures of the body and retvalues don't match, or if // an error if the signatures of the body and retvalues don't match, or if
@ -34,3 +53,8 @@ func (c *Call) Store(retvalues ...interface{}) error {
return Store(c.Body, retvalues...) return Store(c.Body, retvalues...)
} }
func (c *Call) done() {
c.Done <- c
c.ContextCancel()
}

View File

@ -1,10 +1,10 @@
package dbus package dbus
import ( import (
"context"
"errors" "errors"
"io" "io"
"os" "os"
"reflect"
"strings" "strings"
"sync" "sync"
) )
@ -14,7 +14,6 @@ var (
systemBusLck sync.Mutex systemBusLck sync.Mutex
sessionBus *Conn sessionBus *Conn
sessionBusLck sync.Mutex sessionBusLck sync.Mutex
sessionEnvLck sync.Mutex
) )
// ErrClosed is the error returned by calls on a closed connection. // ErrClosed is the error returned by calls on a closed connection.
@ -31,21 +30,25 @@ var ErrClosed = errors.New("dbus: connection closed by user")
type Conn struct { type Conn struct {
transport transport
ctx context.Context
cancelCtx context.CancelFunc
closeOnce sync.Once
closeErr error
busObj BusObject busObj BusObject
unixFD bool unixFD bool
uuid string uuid string
names *nameTracker
serialGen *serialGenerator
calls *callTracker
handler Handler handler Handler
outHandler *outputHandler
signalHandler SignalHandler signalHandler SignalHandler
serialGen SerialGenerator
inInt Interceptor
outInt Interceptor
names *nameTracker
calls *callTracker
outHandler *outputHandler
eavesdropped chan<- *Message eavesdropped chan<- *Message
eavesdroppedLck sync.Mutex eavesdroppedLck sync.Mutex
@ -81,32 +84,31 @@ func SessionBus() (conn *Conn, err error) {
} }
func getSessionBusAddress() (string, error) { func getSessionBusAddress() (string, error) {
sessionEnvLck.Lock() if address := os.Getenv("DBUS_SESSION_BUS_ADDRESS"); address != "" && address != "autolaunch:" {
defer sessionEnvLck.Unlock() return address, nil
address := os.Getenv("DBUS_SESSION_BUS_ADDRESS")
if address != "" && address != "autolaunch:" { } else if address := tryDiscoverDbusSessionBusAddress(); address != "" {
os.Setenv("DBUS_SESSION_BUS_ADDRESS", address)
return address, nil return address, nil
} }
return getSessionBusPlatformAddress() return getSessionBusPlatformAddress()
} }
// SessionBusPrivate returns a new private connection to the session bus. // SessionBusPrivate returns a new private connection to the session bus.
func SessionBusPrivate() (*Conn, error) { func SessionBusPrivate(opts ...ConnOption) (*Conn, error) {
address, err := getSessionBusAddress() address, err := getSessionBusAddress()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return Dial(address) return Dial(address, opts...)
} }
// SessionBusPrivate returns a new private connection to the session bus. // SessionBusPrivate returns a new private connection to the session bus.
//
// Deprecated: use SessionBusPrivate with options instead.
func SessionBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) { func SessionBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) {
address, err := getSessionBusAddress() return SessionBusPrivate(WithHandler(handler), WithSignalHandler(signalHandler))
if err != nil {
return nil, err
}
return DialHandler(address, handler, signalHandler)
} }
// SystemBus returns a shared connection to the system bus, connecting to it if // SystemBus returns a shared connection to the system bus, connecting to it if
@ -139,52 +141,130 @@ func SystemBus() (conn *Conn, err error) {
} }
// SystemBusPrivate returns a new private connection to the system bus. // SystemBusPrivate returns a new private connection to the system bus.
func SystemBusPrivate() (*Conn, error) { // Note: this connection is not ready to use. One must perform Auth and Hello
return Dial(getSystemBusPlatformAddress()) // on the connection before it is useable.
func SystemBusPrivate(opts ...ConnOption) (*Conn, error) {
return Dial(getSystemBusPlatformAddress(), opts...)
} }
// SystemBusPrivateHandler returns a new private connection to the system bus, using the provided handlers. // SystemBusPrivateHandler returns a new private connection to the system bus, using the provided handlers.
//
// Deprecated: use SystemBusPrivate with options instead.
func SystemBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) { func SystemBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) {
return DialHandler(getSystemBusPlatformAddress(), handler, signalHandler) return SystemBusPrivate(WithHandler(handler), WithSignalHandler(signalHandler))
} }
// Dial establishes a new private connection to the message bus specified by address. // Dial establishes a new private connection to the message bus specified by address.
func Dial(address string) (*Conn, error) { func Dial(address string, opts ...ConnOption) (*Conn, error) {
tr, err := getTransport(address) tr, err := getTransport(address)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return newConn(tr, NewDefaultHandler(), NewDefaultSignalHandler()) return newConn(tr, opts...)
} }
// DialHandler establishes a new private connection to the message bus specified by address, using the supplied handlers. // DialHandler establishes a new private connection to the message bus specified by address, using the supplied handlers.
//
// Deprecated: use Dial with options instead.
func DialHandler(address string, handler Handler, signalHandler SignalHandler) (*Conn, error) { func DialHandler(address string, handler Handler, signalHandler SignalHandler) (*Conn, error) {
tr, err := getTransport(address) return Dial(address, WithSignalHandler(signalHandler))
if err != nil { }
return nil, err
// ConnOption is a connection option.
type ConnOption func(conn *Conn) error
// WithHandler overrides the default handler.
func WithHandler(handler Handler) ConnOption {
return func(conn *Conn) error {
conn.handler = handler
return nil
}
}
// WithSignalHandler overrides the default signal handler.
func WithSignalHandler(handler SignalHandler) ConnOption {
return func(conn *Conn) error {
conn.signalHandler = handler
return nil
}
}
// WithSerialGenerator overrides the default signals generator.
func WithSerialGenerator(gen SerialGenerator) ConnOption {
return func(conn *Conn) error {
conn.serialGen = gen
return nil
}
}
// Interceptor intercepts incoming and outgoing messages.
type Interceptor func(msg *Message)
// WithIncomingInterceptor sets the given interceptor for incoming messages.
func WithIncomingInterceptor(interceptor Interceptor) ConnOption {
return func(conn *Conn) error {
conn.inInt = interceptor
return nil
}
}
// WithOutgoingInterceptor sets the given interceptor for outgoing messages.
func WithOutgoingInterceptor(interceptor Interceptor) ConnOption {
return func(conn *Conn) error {
conn.outInt = interceptor
return nil
}
}
// WithContext overrides the default context for the connection.
func WithContext(ctx context.Context) ConnOption {
return func(conn *Conn) error {
conn.ctx = ctx
return nil
} }
return newConn(tr, handler, signalHandler)
} }
// NewConn creates a new private *Conn from an already established connection. // NewConn creates a new private *Conn from an already established connection.
func NewConn(conn io.ReadWriteCloser) (*Conn, error) { func NewConn(conn io.ReadWriteCloser, opts ...ConnOption) (*Conn, error) {
return NewConnHandler(conn, NewDefaultHandler(), NewDefaultSignalHandler()) return newConn(genericTransport{conn}, opts...)
} }
// NewConnHandler creates a new private *Conn from an already established connection, using the supplied handlers. // NewConnHandler creates a new private *Conn from an already established connection, using the supplied handlers.
//
// Deprecated: use NewConn with options instead.
func NewConnHandler(conn io.ReadWriteCloser, handler Handler, signalHandler SignalHandler) (*Conn, error) { func NewConnHandler(conn io.ReadWriteCloser, handler Handler, signalHandler SignalHandler) (*Conn, error) {
return newConn(genericTransport{conn}, handler, signalHandler) return NewConn(genericTransport{conn}, WithHandler(handler), WithSignalHandler(signalHandler))
} }
// newConn creates a new *Conn from a transport. // newConn creates a new *Conn from a transport.
func newConn(tr transport, handler Handler, signalHandler SignalHandler) (*Conn, error) { func newConn(tr transport, opts ...ConnOption) (*Conn, error) {
conn := new(Conn) conn := new(Conn)
conn.transport = tr conn.transport = tr
for _, opt := range opts {
if err := opt(conn); err != nil {
return nil, err
}
}
if conn.ctx == nil {
conn.ctx = context.Background()
}
conn.ctx, conn.cancelCtx = context.WithCancel(conn.ctx)
go func() {
<-conn.ctx.Done()
conn.Close()
}()
conn.calls = newCallTracker() conn.calls = newCallTracker()
conn.handler = handler if conn.handler == nil {
conn.signalHandler = signalHandler conn.handler = NewDefaultHandler()
conn.outHandler = &outputHandler{conn: conn} }
if conn.signalHandler == nil {
conn.signalHandler = NewDefaultSignalHandler()
}
if conn.serialGen == nil {
conn.serialGen = newSerialGenerator() conn.serialGen = newSerialGenerator()
}
conn.outHandler = &outputHandler{conn: conn}
conn.names = newNameTracker() conn.names = newNameTracker()
conn.busObj = conn.Object("org.freedesktop.DBus", "/org/freedesktop/DBus") conn.busObj = conn.Object("org.freedesktop.DBus", "/org/freedesktop/DBus")
return conn, nil return conn, nil
@ -200,6 +280,7 @@ func (conn *Conn) BusObject() BusObject {
// and the channels passed to Eavesdrop and Signal are closed. This method must // and the channels passed to Eavesdrop and Signal are closed. This method must
// not be called on shared connections. // not be called on shared connections.
func (conn *Conn) Close() error { func (conn *Conn) Close() error {
conn.closeOnce.Do(func() {
conn.outHandler.close() conn.outHandler.close()
if term, ok := conn.signalHandler.(Terminator); ok { if term, ok := conn.signalHandler.(Terminator); ok {
term.Terminate() term.Terminate()
@ -215,12 +296,22 @@ func (conn *Conn) Close() error {
} }
conn.eavesdroppedLck.Unlock() conn.eavesdroppedLck.Unlock()
return conn.transport.Close() conn.cancelCtx()
conn.closeErr = conn.transport.Close()
})
return conn.closeErr
}
// Context returns the context associated with the connection. The
// context will be cancelled when the connection is closed.
func (conn *Conn) Context() context.Context {
return conn.ctx
} }
// Eavesdrop causes conn to send all incoming messages to the given channel // Eavesdrop causes conn to send all incoming messages to the given channel
// without further processing. Method replies, errors and signals will not be // without further processing. Method replies, errors and signals will not be
// sent to the appropiate channels and method calls will not be handled. If nil // sent to the appropriate channels and method calls will not be handled. If nil
// is passed, the normal behaviour is restored. // is passed, the normal behaviour is restored.
// //
// The caller has to make sure that ch is sufficiently buffered; // The caller has to make sure that ch is sufficiently buffered;
@ -234,7 +325,7 @@ func (conn *Conn) Eavesdrop(ch chan<- *Message) {
// getSerial returns an unused serial. // getSerial returns an unused serial.
func (conn *Conn) getSerial() uint32 { func (conn *Conn) getSerial() uint32 {
return conn.serialGen.getSerial() return conn.serialGen.GetSerial()
} }
// Hello sends the initial org.freedesktop.DBus.Hello call. This method must be // Hello sends the initial org.freedesktop.DBus.Hello call. This method must be
@ -257,7 +348,7 @@ func (conn *Conn) inWorker() {
msg, err := conn.ReadMessage() msg, err := conn.ReadMessage()
if err != nil { if err != nil {
if _, ok := err.(InvalidMessageError); !ok { if _, ok := err.(InvalidMessageError); !ok {
// Some read error occured (usually EOF); we can't really do // Some read error occurred (usually EOF); we can't really do
// anything but to shut down all stuff and returns errors to all // anything but to shut down all stuff and returns errors to all
// pending replies. // pending replies.
conn.Close() conn.Close()
@ -286,11 +377,15 @@ func (conn *Conn) inWorker() {
// Ignore it. // Ignore it.
continue continue
} }
if conn.inInt != nil {
conn.inInt(msg)
}
switch msg.Type { switch msg.Type {
case TypeError: case TypeError:
conn.serialGen.retireSerial(conn.calls.handleDBusError(msg)) conn.serialGen.RetireSerial(conn.calls.handleDBusError(msg))
case TypeMethodReply: case TypeMethodReply:
conn.serialGen.retireSerial(conn.calls.handleReply(msg)) conn.serialGen.RetireSerial(conn.calls.handleReply(msg))
case TypeSignal: case TypeSignal:
conn.handleSignal(msg) conn.handleSignal(msg)
case TypeMethodCall: case TypeMethodCall:
@ -346,19 +441,16 @@ func (conn *Conn) Object(dest string, path ObjectPath) BusObject {
return &Object{conn, dest, path} return &Object{conn, dest, path}
} }
// outWorker runs in an own goroutine, encoding and sending messages that are
// sent to conn.out.
func (conn *Conn) sendMessage(msg *Message) {
conn.sendMessageAndIfClosed(msg, func() {})
}
func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) { func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) {
if conn.outInt != nil {
conn.outInt(msg)
}
err := conn.outHandler.sendAndIfClosed(msg, ifClosed) err := conn.outHandler.sendAndIfClosed(msg, ifClosed)
conn.calls.handleSendError(msg, err) conn.calls.handleSendError(msg, err)
if err != nil { if err != nil {
conn.serialGen.retireSerial(msg.serial) conn.serialGen.RetireSerial(msg.serial)
} else if msg.Type != TypeMethodCall { } else if msg.Type != TypeMethodCall {
conn.serialGen.retireSerial(msg.serial) conn.serialGen.RetireSerial(msg.serial)
} }
} }
@ -369,8 +461,21 @@ func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) {
// once the call is complete. Otherwise, ch is ignored and a Call structure is // once the call is complete. Otherwise, ch is ignored and a Call structure is
// returned of which only the Err member is valid. // returned of which only the Err member is valid.
func (conn *Conn) Send(msg *Message, ch chan *Call) *Call { func (conn *Conn) Send(msg *Message, ch chan *Call) *Call {
var call *Call return conn.send(context.Background(), msg, ch)
}
// SendWithContext acts like Send but takes a context
func (conn *Conn) SendWithContext(ctx context.Context, msg *Message, ch chan *Call) *Call {
return conn.send(ctx, msg, ch)
}
func (conn *Conn) send(ctx context.Context, msg *Message, ch chan *Call) *Call {
if ctx == nil {
panic("nil context")
}
var call *Call
ctx, canceler := context.WithCancel(ctx)
msg.serial = conn.getSerial() msg.serial = conn.getSerial()
if msg.Type == TypeMethodCall && msg.Flags&FlagNoReplyExpected == 0 { if msg.Type == TypeMethodCall && msg.Flags&FlagNoReplyExpected == 0 {
if ch == nil { if ch == nil {
@ -386,12 +491,19 @@ func (conn *Conn) Send(msg *Message, ch chan *Call) *Call {
call.Method = iface + "." + member call.Method = iface + "." + member
call.Args = msg.Body call.Args = msg.Body
call.Done = ch call.Done = ch
call.ctx = ctx
call.ctxCanceler = canceler
conn.calls.track(msg.serial, call) conn.calls.track(msg.serial, call)
go func() {
<-ctx.Done()
conn.calls.handleSendError(msg, ctx.Err())
}()
conn.sendMessageAndIfClosed(msg, func() { conn.sendMessageAndIfClosed(msg, func() {
call.Err = ErrClosed conn.calls.handleSendError(msg, ErrClosed)
call.Done <- call canceler()
}) })
} else { } else {
canceler()
call = &Call{Err: nil} call = &Call{Err: nil}
conn.sendMessageAndIfClosed(msg, func() { conn.sendMessageAndIfClosed(msg, func() {
call = &Call{Err: ErrClosed} call = &Call{Err: ErrClosed}
@ -428,7 +540,7 @@ func (conn *Conn) sendError(err error, dest string, serial uint32) {
if len(e.Body) > 0 { if len(e.Body) > 0 {
msg.Headers[FieldSignature] = MakeVariant(SignatureOf(e.Body...)) msg.Headers[FieldSignature] = MakeVariant(SignatureOf(e.Body...))
} }
conn.sendMessage(msg) conn.sendMessageAndIfClosed(msg, nil)
} }
// sendReply creates a method reply message corresponding to the parameters and // sendReply creates a method reply message corresponding to the parameters and
@ -446,33 +558,54 @@ func (conn *Conn) sendReply(dest string, serial uint32, values ...interface{}) {
if len(values) > 0 { if len(values) > 0 {
msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...)) msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...))
} }
conn.sendMessage(msg) conn.sendMessageAndIfClosed(msg, nil)
} }
func (conn *Conn) defaultSignalAction(fn func(h *defaultSignalHandler, ch chan<- *Signal), ch chan<- *Signal) { // AddMatchSignal registers the given match rule to receive broadcast
if !isDefaultSignalHandler(conn.signalHandler) { // signals based on their contents.
return func (conn *Conn) AddMatchSignal(options ...MatchOption) error {
} options = append([]MatchOption{withMatchType("signal")}, options...)
handler := conn.signalHandler.(*defaultSignalHandler) return conn.busObj.Call(
fn(handler, ch) "org.freedesktop.DBus.AddMatch", 0,
formatMatchOptions(options),
).Store()
}
// RemoveMatchSignal removes the first rule that matches previously registered with AddMatchSignal.
func (conn *Conn) RemoveMatchSignal(options ...MatchOption) error {
options = append([]MatchOption{withMatchType("signal")}, options...)
return conn.busObj.Call(
"org.freedesktop.DBus.RemoveMatch", 0,
formatMatchOptions(options),
).Store()
} }
// Signal registers the given channel to be passed all received signal messages. // Signal registers the given channel to be passed all received signal messages.
// The caller has to make sure that ch is sufficiently buffered; if a message
// arrives when a write to c is not possible, it is discarded.
// //
// Multiple of these channels can be registered at the same time. // Multiple of these channels can be registered at the same time.
// //
// These channels are "overwritten" by Eavesdrop; i.e., if there currently is a // These channels are "overwritten" by Eavesdrop; i.e., if there currently is a
// channel for eavesdropped messages, this channel receives all signals, and // channel for eavesdropped messages, this channel receives all signals, and
// none of the channels passed to Signal will receive any signals. // none of the channels passed to Signal will receive any signals.
//
// Panics if the signal handler is not a `SignalRegistrar`.
func (conn *Conn) Signal(ch chan<- *Signal) { func (conn *Conn) Signal(ch chan<- *Signal) {
conn.defaultSignalAction((*defaultSignalHandler).addSignal, ch) handler, ok := conn.signalHandler.(SignalRegistrar)
if !ok {
panic("cannot use this method with a non SignalRegistrar handler")
}
handler.AddSignal(ch)
} }
// RemoveSignal removes the given channel from the list of the registered channels. // RemoveSignal removes the given channel from the list of the registered channels.
//
// Panics if the signal handler is not a `SignalRegistrar`.
func (conn *Conn) RemoveSignal(ch chan<- *Signal) { func (conn *Conn) RemoveSignal(ch chan<- *Signal) {
conn.defaultSignalAction((*defaultSignalHandler).removeSignal, ch) handler, ok := conn.signalHandler.(SignalRegistrar)
if !ok {
panic("cannot use this method with a non SignalRegistrar handler")
}
handler.RemoveSignal(ch)
} }
// SupportsUnixFDs returns whether the underlying transport supports passing of // SupportsUnixFDs returns whether the underlying transport supports passing of
@ -559,18 +692,6 @@ func getTransport(address string) (transport, error) {
return nil, err return nil, err
} }
// dereferenceAll returns a slice that, assuming that vs is a slice of pointers
// of arbitrary types, containes the values that are obtained from dereferencing
// all elements in vs.
func dereferenceAll(vs []interface{}) []interface{} {
for i := range vs {
v := reflect.ValueOf(vs[i])
v = v.Elem()
vs[i] = v.Interface()
}
return vs
}
// getKey gets a key from a the list of keys. Returns "" on error / not found... // getKey gets a key from a the list of keys. Returns "" on error / not found...
func getKey(s, key string) string { func getKey(s, key string) string {
for _, keyEqualsValue := range strings.Split(s, ",") { for _, keyEqualsValue := range strings.Split(s, ",") {
@ -595,7 +716,9 @@ func (h *outputHandler) sendAndIfClosed(msg *Message, ifClosed func()) error {
h.closed.lck.RLock() h.closed.lck.RLock()
defer h.closed.lck.RUnlock() defer h.closed.lck.RUnlock()
if h.closed.isClosed { if h.closed.isClosed {
if ifClosed != nil {
ifClosed() ifClosed()
}
return nil return nil
} }
h.sendLck.Lock() h.sendLck.Lock()
@ -622,7 +745,7 @@ func newSerialGenerator() *serialGenerator {
} }
} }
func (gen *serialGenerator) getSerial() uint32 { func (gen *serialGenerator) GetSerial() uint32 {
gen.lck.Lock() gen.lck.Lock()
defer gen.lck.Unlock() defer gen.lck.Unlock()
n := gen.nextSerial n := gen.nextSerial
@ -634,7 +757,7 @@ func (gen *serialGenerator) getSerial() uint32 {
return n return n
} }
func (gen *serialGenerator) retireSerial(serial uint32) { func (gen *serialGenerator) RetireSerial(serial uint32) {
gen.lck.Lock() gen.lck.Lock()
defer gen.lck.Unlock() defer gen.lck.Unlock()
delete(gen.serialUsed, serial) delete(gen.serialUsed, serial)
@ -698,36 +821,30 @@ func newCallTracker() *callTracker {
func (tracker *callTracker) track(sn uint32, call *Call) { func (tracker *callTracker) track(sn uint32, call *Call) {
tracker.lck.Lock() tracker.lck.Lock()
defer tracker.lck.Unlock()
tracker.calls[sn] = call tracker.calls[sn] = call
tracker.lck.Unlock()
} }
func (tracker *callTracker) handleReply(msg *Message) uint32 { func (tracker *callTracker) handleReply(msg *Message) uint32 {
serial := msg.Headers[FieldReplySerial].value.(uint32) serial := msg.Headers[FieldReplySerial].value.(uint32)
tracker.lck.RLock() tracker.lck.RLock()
c, ok := tracker.calls[serial] _, ok := tracker.calls[serial]
tracker.lck.RUnlock() tracker.lck.RUnlock()
if !ok { if ok {
return serial tracker.finalizeWithBody(serial, msg.Body)
} }
c.Body = msg.Body
c.Done <- c
tracker.finalize(serial)
return serial return serial
} }
func (tracker *callTracker) handleDBusError(msg *Message) uint32 { func (tracker *callTracker) handleDBusError(msg *Message) uint32 {
serial := msg.Headers[FieldReplySerial].value.(uint32) serial := msg.Headers[FieldReplySerial].value.(uint32)
tracker.lck.RLock() tracker.lck.RLock()
c, ok := tracker.calls[serial] _, ok := tracker.calls[serial]
tracker.lck.RUnlock() tracker.lck.RUnlock()
if !ok { if ok {
return serial
}
name, _ := msg.Headers[FieldErrorName].value.(string) name, _ := msg.Headers[FieldErrorName].value.(string)
c.Err = Error{name, msg.Body} tracker.finalizeWithError(serial, Error{name, msg.Body})
c.Done <- c }
tracker.finalize(serial)
return serial return serial
} }
@ -736,32 +853,60 @@ func (tracker *callTracker) handleSendError(msg *Message, err error) {
return return
} }
tracker.lck.RLock() tracker.lck.RLock()
c, ok := tracker.calls[msg.serial] _, ok := tracker.calls[msg.serial]
tracker.lck.RUnlock() tracker.lck.RUnlock()
if !ok { if ok {
return tracker.finalizeWithError(msg.serial, err)
} }
c.Err = err
c.Done <- c
tracker.finalize(msg.serial)
} }
// finalize was the only func that did not strobe Done
func (tracker *callTracker) finalize(sn uint32) { func (tracker *callTracker) finalize(sn uint32) {
tracker.lck.Lock() tracker.lck.Lock()
defer tracker.lck.Unlock() defer tracker.lck.Unlock()
c, ok := tracker.calls[sn]
if ok {
delete(tracker.calls, sn) delete(tracker.calls, sn)
c.ContextCancel()
}
}
func (tracker *callTracker) finalizeWithBody(sn uint32, body []interface{}) {
tracker.lck.Lock()
c, ok := tracker.calls[sn]
if ok {
delete(tracker.calls, sn)
}
tracker.lck.Unlock()
if ok {
c.Body = body
c.done()
}
}
func (tracker *callTracker) finalizeWithError(sn uint32, err error) {
tracker.lck.Lock()
c, ok := tracker.calls[sn]
if ok {
delete(tracker.calls, sn)
}
tracker.lck.Unlock()
if ok {
c.Err = err
c.done()
}
} }
func (tracker *callTracker) finalizeAllWithError(err error) { func (tracker *callTracker) finalizeAllWithError(err error) {
closedCalls := make(map[uint32]*Call) tracker.lck.Lock()
tracker.lck.RLock() closedCalls := make([]*Call, 0, len(tracker.calls))
for sn, v := range tracker.calls { for sn := range tracker.calls {
v.Err = err closedCalls = append(closedCalls, tracker.calls[sn])
v.Done <- v
closedCalls[sn] = v
} }
tracker.lck.RUnlock() tracker.calls = map[uint32]*Call{}
for sn := range closedCalls { tracker.lck.Unlock()
tracker.finalize(sn) for _, call := range closedCalls {
call.Err = err
call.done()
} }
} }

View File

@ -31,3 +31,7 @@ func getSystemBusPlatformAddress() string {
} }
return defaultSystemBusAddress return defaultSystemBusAddress
} }
func tryDiscoverDbusSessionBusAddress() string {
return ""
}

93
vendor/github.com/godbus/dbus/v5/conn_other.go generated vendored Normal file
View File

@ -0,0 +1,93 @@
// +build !darwin
package dbus
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"os/exec"
"os/user"
"path"
"strings"
)
var execCommand = exec.Command
func getSessionBusPlatformAddress() (string, error) {
cmd := execCommand("dbus-launch")
b, err := cmd.CombinedOutput()
if err != nil {
return "", err
}
i := bytes.IndexByte(b, '=')
j := bytes.IndexByte(b, '\n')
if i == -1 || j == -1 || i > j {
return "", errors.New("dbus: couldn't determine address of session bus")
}
env, addr := string(b[0:i]), string(b[i+1:j])
os.Setenv(env, addr)
return addr, nil
}
// tryDiscoverDbusSessionBusAddress tries to discover an existing dbus session
// and return the value of its DBUS_SESSION_BUS_ADDRESS.
// It tries different techniques employed by different operating systems,
// returning the first valid address it finds, or an empty string.
//
// * /run/user/<uid>/bus if this exists, it *is* the bus socket. present on
// Ubuntu 18.04
// * /run/user/<uid>/dbus-session: if this exists, it can be parsed for the bus
// address. present on Ubuntu 16.04
//
// See https://dbus.freedesktop.org/doc/dbus-launch.1.html
func tryDiscoverDbusSessionBusAddress() string {
if runtimeDirectory, err := getRuntimeDirectory(); err == nil {
if runUserBusFile := path.Join(runtimeDirectory, "bus"); fileExists(runUserBusFile) {
// if /run/user/<uid>/bus exists, that file itself
// *is* the unix socket, so return its path
return fmt.Sprintf("unix:path=%s", runUserBusFile)
}
if runUserSessionDbusFile := path.Join(runtimeDirectory, "dbus-session"); fileExists(runUserSessionDbusFile) {
// if /run/user/<uid>/dbus-session exists, it's a
// text file // containing the address of the socket, e.g.:
// DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-E1c73yNqrG
if f, err := ioutil.ReadFile(runUserSessionDbusFile); err == nil {
fileContent := string(f)
prefix := "DBUS_SESSION_BUS_ADDRESS="
if strings.HasPrefix(fileContent, prefix) {
address := strings.TrimRight(strings.TrimPrefix(fileContent, prefix), "\n\r")
return address
}
}
}
}
return ""
}
func getRuntimeDirectory() (string, error) {
if currentUser, err := user.Current(); err != nil {
return "", err
} else {
return fmt.Sprintf("/run/user/%s", currentUser.Uid), nil
}
}
func fileExists(filename string) bool {
if _, err := os.Stat(filename); !os.IsNotExist(err) {
return true
} else {
return false
}
}

17
vendor/github.com/godbus/dbus/v5/conn_unix.go generated vendored Normal file
View File

@ -0,0 +1,17 @@
//+build !windows,!solaris,!darwin
package dbus
import (
"os"
)
const defaultSystemBusAddress = "unix:path=/var/run/dbus/system_bus_socket"
func getSystemBusPlatformAddress() string {
address := os.Getenv("DBUS_SYSTEM_BUS_ADDRESS")
if address != "" {
return address
}
return defaultSystemBusAddress
}

15
vendor/github.com/godbus/dbus/v5/conn_windows.go generated vendored Normal file
View File

@ -0,0 +1,15 @@
//+build windows
package dbus
import "os"
const defaultSystemBusAddress = "tcp:host=127.0.0.1,port=12434"
func getSystemBusPlatformAddress() string {
address := os.Getenv("DBUS_SYSTEM_BUS_ADDRESS")
if address != "" {
return address
}
return defaultSystemBusAddress
}

View File

@ -87,6 +87,7 @@ func setDest(dest, src reflect.Value) error {
} }
if isVariant(src.Type()) && !isVariant(dest.Type()) { if isVariant(src.Type()) && !isVariant(dest.Type()) {
src = getVariantValue(src) src = getVariantValue(src)
return store(dest, src)
} }
if !src.Type().ConvertibleTo(dest.Type()) { if !src.Type().ConvertibleTo(dest.Type()) {
return fmt.Errorf( return fmt.Errorf(

View File

@ -188,10 +188,23 @@ func (dec *decoder) decode(s string, depth int) interface{} {
if depth >= 64 { if depth >= 64 {
panic(FormatError("input exceeds container depth limit")) panic(FormatError("input exceeds container depth limit"))
} }
sig := s[1:]
length := dec.decode("u", depth).(uint32) length := dec.decode("u", depth).(uint32)
v := reflect.MakeSlice(reflect.SliceOf(typeFor(s[1:])), 0, int(length)) // capacity can be determined only for fixed-size element types
var capacity int
if s := sigByteSize(sig); s != 0 {
capacity = int(length) / s
}
v := reflect.MakeSlice(reflect.SliceOf(typeFor(sig)), 0, capacity)
// Even for empty arrays, the correct padding must be included // Even for empty arrays, the correct padding must be included
dec.align(alignment(typeFor(s[1:]))) align := alignment(typeFor(s[1:]))
if len(s) > 1 && s[1] == '(' {
//Special case for arrays of structs
//structs decode as a slice of interface{} values
//but the dbus alignment does not match this
align = 8
}
dec.align(align)
spos := dec.pos spos := dec.pos
for dec.pos < spos+int(length) { for dec.pos < spos+int(length) {
ev := dec.decode(s[1:], depth+1) ev := dec.decode(s[1:], depth+1)
@ -220,6 +233,51 @@ func (dec *decoder) decode(s string, depth int) interface{} {
} }
} }
// sigByteSize tries to calculates size of the given signature in bytes.
//
// It returns zero when it can't, for example when it contains non-fixed size
// types such as strings, maps and arrays that require reading of the transmitted
// data, for that we would need to implement the unread method for Decoder first.
func sigByteSize(sig string) int {
var total int
for offset := 0; offset < len(sig); {
switch sig[offset] {
case 'y':
total += 1
offset += 1
case 'n', 'q':
total += 2
offset += 1
case 'b', 'i', 'u', 'h':
total += 4
offset += 1
case 'x', 't', 'd':
total += 8
offset += 1
case '(':
i := 1
depth := 1
for i < len(sig[offset:]) && depth != 0 {
if sig[offset+i] == '(' {
depth++
} else if sig[offset+i] == ')' {
depth--
}
i++
}
s := sigByteSize(sig[offset+1 : offset+i-1])
if s == 0 {
return 0
}
total += s
offset += i
default:
return 0
}
}
return total
}
// A FormatError is an error in the wire format. // A FormatError is an error in the wire format.
type FormatError string type FormatError string

View File

@ -21,6 +21,8 @@ func newIntrospectIntf(h *defaultHandler) *exportedIntf {
//NewDefaultHandler returns an instance of the default //NewDefaultHandler returns an instance of the default
//call handler. This is useful if you want to implement only //call handler. This is useful if you want to implement only
//one of the two handlers but not both. //one of the two handlers but not both.
//
// Deprecated: this is the default value, don't use it, it will be unexported.
func NewDefaultHandler() *defaultHandler { func NewDefaultHandler() *defaultHandler {
h := &defaultHandler{ h := &defaultHandler{
objects: make(map[ObjectPath]*exportedObj), objects: make(map[ObjectPath]*exportedObj),
@ -45,7 +47,7 @@ func (h *defaultHandler) introspectPath(path ObjectPath) string {
subpath := make(map[string]struct{}) subpath := make(map[string]struct{})
var xml bytes.Buffer var xml bytes.Buffer
xml.WriteString("<node>") xml.WriteString("<node>")
for obj, _ := range h.objects { for obj := range h.objects {
p := string(path) p := string(path)
if p != "/" { if p != "/" {
p += "/" p += "/"
@ -55,7 +57,7 @@ func (h *defaultHandler) introspectPath(path ObjectPath) string {
subpath[node_name] = struct{}{} subpath[node_name] = struct{}{}
} }
} }
for s, _ := range subpath { for s := range subpath {
xml.WriteString("\n\t<node name=\"" + s + "\"/>") xml.WriteString("\n\t<node name=\"" + s + "\"/>")
} }
xml.WriteString("\n</node>") xml.WriteString("\n</node>")
@ -161,6 +163,7 @@ func newExportedObject() *exportedObj {
} }
type exportedObj struct { type exportedObj struct {
mu sync.RWMutex
interfaces map[string]*exportedIntf interfaces map[string]*exportedIntf
} }
@ -168,19 +171,27 @@ func (obj *exportedObj) LookupInterface(name string) (Interface, bool) {
if name == "" { if name == "" {
return obj, true return obj, true
} }
obj.mu.RLock()
defer obj.mu.RUnlock()
intf, exists := obj.interfaces[name] intf, exists := obj.interfaces[name]
return intf, exists return intf, exists
} }
func (obj *exportedObj) AddInterface(name string, iface *exportedIntf) { func (obj *exportedObj) AddInterface(name string, iface *exportedIntf) {
obj.mu.Lock()
defer obj.mu.Unlock()
obj.interfaces[name] = iface obj.interfaces[name] = iface
} }
func (obj *exportedObj) DeleteInterface(name string) { func (obj *exportedObj) DeleteInterface(name string) {
obj.mu.Lock()
defer obj.mu.Unlock()
delete(obj.interfaces, name) delete(obj.interfaces, name)
} }
func (obj *exportedObj) LookupMethod(name string) (Method, bool) { func (obj *exportedObj) LookupMethod(name string) (Method, bool) {
obj.mu.RLock()
defer obj.mu.RUnlock()
for _, intf := range obj.interfaces { for _, intf := range obj.interfaces {
method, exists := intf.LookupMethod(name) method, exists := intf.LookupMethod(name)
if exists { if exists {
@ -220,72 +231,98 @@ func (obj *exportedIntf) isFallbackInterface() bool {
//NewDefaultSignalHandler returns an instance of the default //NewDefaultSignalHandler returns an instance of the default
//signal handler. This is useful if you want to implement only //signal handler. This is useful if you want to implement only
//one of the two handlers but not both. //one of the two handlers but not both.
//
// Deprecated: this is the default value, don't use it, it will be unexported.
func NewDefaultSignalHandler() *defaultSignalHandler { func NewDefaultSignalHandler() *defaultSignalHandler {
return &defaultSignalHandler{} return &defaultSignalHandler{}
} }
func isDefaultSignalHandler(handler SignalHandler) bool {
_, ok := handler.(*defaultSignalHandler)
return ok
}
type defaultSignalHandler struct { type defaultSignalHandler struct {
sync.RWMutex mu sync.RWMutex
closed bool closed bool
signals []chan<- *Signal signals []*signalChannelData
} }
func (sh *defaultSignalHandler) DeliverSignal(intf, name string, signal *Signal) { func (sh *defaultSignalHandler) DeliverSignal(intf, name string, signal *Signal) {
go func() { sh.mu.RLock()
sh.RLock() defer sh.mu.RUnlock()
defer sh.RUnlock()
if sh.closed { if sh.closed {
return return
} }
for _, ch := range sh.signals { for _, scd := range sh.signals {
ch <- signal scd.deliver(signal)
} }
}()
}
func (sh *defaultSignalHandler) Init() error {
sh.Lock()
sh.signals = make([]chan<- *Signal, 0)
sh.Unlock()
return nil
} }
func (sh *defaultSignalHandler) Terminate() { func (sh *defaultSignalHandler) Terminate() {
sh.Lock() sh.mu.Lock()
sh.closed = true defer sh.mu.Unlock()
for _, ch := range sh.signals {
close(ch)
}
sh.signals = nil
sh.Unlock()
}
func (sh *defaultSignalHandler) addSignal(ch chan<- *Signal) {
sh.Lock()
defer sh.Unlock()
if sh.closed { if sh.closed {
return return
} }
sh.signals = append(sh.signals, ch)
for _, scd := range sh.signals {
scd.close()
close(scd.ch)
}
sh.closed = true
sh.signals = nil
} }
func (sh *defaultSignalHandler) removeSignal(ch chan<- *Signal) { func (sh *defaultSignalHandler) AddSignal(ch chan<- *Signal) {
sh.Lock() sh.mu.Lock()
defer sh.Unlock() defer sh.mu.Unlock()
if sh.closed {
return
}
sh.signals = append(sh.signals, &signalChannelData{
ch: ch,
done: make(chan struct{}),
})
}
func (sh *defaultSignalHandler) RemoveSignal(ch chan<- *Signal) {
sh.mu.Lock()
defer sh.mu.Unlock()
if sh.closed { if sh.closed {
return return
} }
for i := len(sh.signals) - 1; i >= 0; i-- { for i := len(sh.signals) - 1; i >= 0; i-- {
if ch == sh.signals[i] { if ch == sh.signals[i].ch {
sh.signals[i].close()
copy(sh.signals[i:], sh.signals[i+1:]) copy(sh.signals[i:], sh.signals[i+1:])
sh.signals[len(sh.signals)-1] = nil sh.signals[len(sh.signals)-1] = nil
sh.signals = sh.signals[:len(sh.signals)-1] sh.signals = sh.signals[:len(sh.signals)-1]
} }
} }
} }
type signalChannelData struct {
wg sync.WaitGroup
ch chan<- *Signal
done chan struct{}
}
func (scd *signalChannelData) deliver(signal *Signal) {
select {
case scd.ch <- signal:
case <-scd.done:
return
default:
scd.wg.Add(1)
go scd.deferredDeliver(signal)
}
}
func (scd *signalChannelData) deferredDeliver(signal *Signal) {
select {
case scd.ch <- signal:
case <-scd.done:
}
scd.wg.Done()
}
func (scd *signalChannelData) close() {
close(scd.done)
scd.wg.Wait() // wait until all spawned goroutines return
}

View File

@ -61,7 +61,7 @@ Handling Unix file descriptors deserves special mention. To use them, you should
first check that they are supported on a connection by calling SupportsUnixFDs. first check that they are supported on a connection by calling SupportsUnixFDs.
If it returns true, all method of Connection will translate messages containing If it returns true, all method of Connection will translate messages containing
UnixFD's to messages that are accompanied by the given file descriptors with the UnixFD's to messages that are accompanied by the given file descriptors with the
UnixFD values being substituted by the correct indices. Similarily, the indices UnixFD values being substituted by the correct indices. Similarly, the indices
of incoming messages are automatically resolved. It shouldn't be necessary to use of incoming messages are automatically resolved. It shouldn't be necessary to use
UnixFDIndex. UnixFDIndex.

View File

@ -60,7 +60,7 @@ func (enc *encoder) binwrite(v interface{}) {
} }
} }
// Encode encodes the given values to the underyling reader. All written values // Encode encodes the given values to the underlying reader. All written values
// are aligned properly as required by the D-Bus spec. // are aligned properly as required by the D-Bus spec.
func (enc *encoder) Encode(vs ...interface{}) (err error) { func (enc *encoder) Encode(vs ...interface{}) (err error) {
defer func() { defer func() {

View File

@ -171,7 +171,7 @@ func (conn *Conn) handleCall(msg *Message) {
} }
reply.Headers[FieldSignature] = MakeVariant(SignatureOf(reply.Body...)) reply.Headers[FieldSignature] = MakeVariant(SignatureOf(reply.Body...))
conn.sendMessage(reply) conn.sendMessageAndIfClosed(reply, nil)
} }
} }

3
vendor/github.com/godbus/dbus/v5/go.mod generated vendored Normal file
View File

@ -0,0 +1,3 @@
module github.com/godbus/dbus/v5
go 1.12

0
vendor/github.com/godbus/dbus/v5/go.sum generated vendored Normal file
View File

62
vendor/github.com/godbus/dbus/v5/match.go generated vendored Normal file
View File

@ -0,0 +1,62 @@
package dbus
import (
"strings"
)
// MatchOption specifies option for dbus routing match rule. Options can be constructed with WithMatch* helpers.
// For full list of available options consult
// https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules
type MatchOption struct {
key string
value string
}
func formatMatchOptions(options []MatchOption) string {
items := make([]string, 0, len(options))
for _, option := range options {
items = append(items, option.key+"='"+option.value+"'")
}
return strings.Join(items, ",")
}
// WithMatchOption creates match option with given key and value
func WithMatchOption(key, value string) MatchOption {
return MatchOption{key, value}
}
// doesn't make sense to export this option because clients can only
// subscribe to messages with signal type.
func withMatchType(typ string) MatchOption {
return WithMatchOption("type", typ)
}
// WithMatchSender sets sender match option.
func WithMatchSender(sender string) MatchOption {
return WithMatchOption("sender", sender)
}
// WithMatchSender sets interface match option.
func WithMatchInterface(iface string) MatchOption {
return WithMatchOption("interface", iface)
}
// WithMatchMember sets member match option.
func WithMatchMember(member string) MatchOption {
return WithMatchOption("member", member)
}
// WithMatchObjectPath creates match option that filters events based on given path
func WithMatchObjectPath(path ObjectPath) MatchOption {
return WithMatchOption("path", string(path))
}
// WithMatchPathNamespace sets path_namespace match option.
func WithMatchPathNamespace(namespace ObjectPath) MatchOption {
return WithMatchOption("path_namespace", string(namespace))
}
// WithMatchDestination sets destination match option.
func WithMatchDestination(destination string) MatchOption {
return WithMatchOption("destination", destination)
}

View File

@ -1,6 +1,7 @@
package dbus package dbus
import ( import (
"context"
"errors" "errors"
"strings" "strings"
) )
@ -9,8 +10,13 @@ import (
// invoked. // invoked.
type BusObject interface { type BusObject interface {
Call(method string, flags Flags, args ...interface{}) *Call Call(method string, flags Flags, args ...interface{}) *Call
CallWithContext(ctx context.Context, method string, flags Flags, args ...interface{}) *Call
Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call
GoWithContext(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call
AddMatchSignal(iface, member string, options ...MatchOption) *Call
RemoveMatchSignal(iface, member string, options ...MatchOption) *Call
GetProperty(p string) (Variant, error) GetProperty(p string) (Variant, error)
SetProperty(p string, v interface{}) error
Destination() string Destination() string
Path() ObjectPath Path() ObjectPath
} }
@ -24,16 +30,50 @@ type Object struct {
// Call calls a method with (*Object).Go and waits for its reply. // Call calls a method with (*Object).Go and waits for its reply.
func (o *Object) Call(method string, flags Flags, args ...interface{}) *Call { func (o *Object) Call(method string, flags Flags, args ...interface{}) *Call {
return <-o.Go(method, flags, make(chan *Call, 1), args...).Done return <-o.createCall(context.Background(), method, flags, make(chan *Call, 1), args...).Done
} }
// AddMatchSignal subscribes BusObject to signals from specified interface and // CallWithContext acts like Call but takes a context
// method (member). func (o *Object) CallWithContext(ctx context.Context, method string, flags Flags, args ...interface{}) *Call {
func (o *Object) AddMatchSignal(iface, member string) *Call { return <-o.createCall(ctx, method, flags, make(chan *Call, 1), args...).Done
return o.Call( }
// AddMatchSignal subscribes BusObject to signals from specified interface,
// method (member). Additional filter rules can be added via WithMatch* option constructors.
// Note: To filter events by object path you have to specify this path via an option.
//
// Deprecated: use (*Conn) AddMatchSignal instead.
func (o *Object) AddMatchSignal(iface, member string, options ...MatchOption) *Call {
base := []MatchOption{
withMatchType("signal"),
WithMatchInterface(iface),
WithMatchMember(member),
}
options = append(base, options...)
return o.conn.BusObject().Call(
"org.freedesktop.DBus.AddMatch", "org.freedesktop.DBus.AddMatch",
0, 0,
"type='signal',interface='"+iface+"',member='"+member+"'", formatMatchOptions(options),
)
}
// RemoveMatchSignal unsubscribes BusObject from signals from specified interface,
// method (member). Additional filter rules can be added via WithMatch* option constructors
//
// Deprecated: use (*Conn) RemoveMatchSignal instead.
func (o *Object) RemoveMatchSignal(iface, member string, options ...MatchOption) *Call {
base := []MatchOption{
withMatchType("signal"),
WithMatchInterface(iface),
WithMatchMember(member),
}
options = append(base, options...)
return o.conn.BusObject().Call(
"org.freedesktop.DBus.RemoveMatch",
0,
formatMatchOptions(options),
) )
} }
@ -49,6 +89,18 @@ func (o *Object) AddMatchSignal(iface, member string) *Call {
// If the method parameter contains a dot ('.'), the part before the last dot // If the method parameter contains a dot ('.'), the part before the last dot
// specifies the interface on which the method is called. // specifies the interface on which the method is called.
func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call { func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call {
return o.createCall(context.Background(), method, flags, ch, args...)
}
// GoWithContext acts like Go but takes a context
func (o *Object) GoWithContext(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call {
return o.createCall(ctx, method, flags, ch, args...)
}
func (o *Object) createCall(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call {
if ctx == nil {
panic("nil context")
}
iface := "" iface := ""
i := strings.LastIndex(method, ".") i := strings.LastIndex(method, ".")
if i != -1 { if i != -1 {
@ -72,22 +124,30 @@ func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface
} }
if msg.Flags&FlagNoReplyExpected == 0 { if msg.Flags&FlagNoReplyExpected == 0 {
if ch == nil { if ch == nil {
ch = make(chan *Call, 10) ch = make(chan *Call, 1)
} else if cap(ch) == 0 { } else if cap(ch) == 0 {
panic("dbus: unbuffered channel passed to (*Object).Go") panic("dbus: unbuffered channel passed to (*Object).Go")
} }
ctx, cancel := context.WithCancel(ctx)
call := &Call{ call := &Call{
Destination: o.dest, Destination: o.dest,
Path: o.path, Path: o.path,
Method: method, Method: method,
Args: args, Args: args,
Done: ch, Done: ch,
ctxCanceler: cancel,
ctx: ctx,
} }
o.conn.calls.track(msg.serial, call) o.conn.calls.track(msg.serial, call)
o.conn.sendMessageAndIfClosed(msg, func() { o.conn.sendMessageAndIfClosed(msg, func() {
call.Err = ErrClosed o.conn.calls.handleSendError(msg, ErrClosed)
call.Done <- call cancel()
}) })
go func() {
<-ctx.Done()
o.conn.calls.handleSendError(msg, ctx.Err())
}()
return call return call
} }
done := make(chan *Call, 1) done := make(chan *Call, 1)
@ -105,7 +165,7 @@ func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface
return call return call
} }
// GetProperty calls org.freedesktop.DBus.Properties.GetProperty on the given // GetProperty calls org.freedesktop.DBus.Properties.Get on the given
// object. The property name must be given in interface.member notation. // object. The property name must be given in interface.member notation.
func (o *Object) GetProperty(p string) (Variant, error) { func (o *Object) GetProperty(p string) (Variant, error) {
idx := strings.LastIndex(p, ".") idx := strings.LastIndex(p, ".")
@ -126,6 +186,20 @@ func (o *Object) GetProperty(p string) (Variant, error) {
return result, nil return result, nil
} }
// SetProperty calls org.freedesktop.DBus.Properties.Set on the given
// object. The property name must be given in interface.member notation.
func (o *Object) SetProperty(p string, v interface{}) error {
idx := strings.LastIndex(p, ".")
if idx == -1 || idx+1 == len(p) {
return errors.New("dbus: invalid property " + p)
}
iface := p[:idx]
prop := p[idx+1:]
return o.Call("org.freedesktop.DBus.Properties.Set", 0, iface, prop, v).Err
}
// Destination returns the destination that calls on (o *Object) are sent to. // Destination returns the destination that calls on (o *Object) are sent to.
func (o *Object) Destination() string { func (o *Object) Destination() string {
return o.dest return o.dest

View File

@ -77,6 +77,14 @@ type SignalHandler interface {
DeliverSignal(iface, name string, signal *Signal) DeliverSignal(iface, name string, signal *Signal)
} }
// SignalRegistrar manages signal delivery channels.
//
// This is an optional set of methods for `SignalHandler`.
type SignalRegistrar interface {
AddSignal(ch chan<- *Signal)
RemoveSignal(ch chan<- *Signal)
}
// A DBusError is used to convert a generic object to a D-Bus error. // A DBusError is used to convert a generic object to a D-Bus error.
// //
// Any custom error mechanism may implement this interface to provide // Any custom error mechanism may implement this interface to provide
@ -87,3 +95,13 @@ type SignalHandler interface {
type DBusError interface { type DBusError interface {
DBusError() (string, []interface{}) DBusError() (string, []interface{})
} }
// SerialGenerator is responsible for serials generation.
//
// Different approaches for the serial generation can be used,
// maintaining a map guarded with a mutex (the standard way) or
// simply increment an atomic counter.
type SerialGenerator interface {
GetSerial() uint32
RetireSerial(serial uint32)
}

View File

@ -0,0 +1,39 @@
//+build !windows
package dbus
import (
"errors"
"io/ioutil"
"net"
)
func init() {
transports["nonce-tcp"] = newNonceTcpTransport
}
func newNonceTcpTransport(keys string) (transport, error) {
host := getKey(keys, "host")
port := getKey(keys, "port")
noncefile := getKey(keys, "noncefile")
if host == "" || port == "" || noncefile == "" {
return nil, errors.New("dbus: unsupported address (must set host, port and noncefile)")
}
protocol, err := tcpFamily(keys)
if err != nil {
return nil, err
}
socket, err := net.Dial(protocol, net.JoinHostPort(host, port))
if err != nil {
return nil, err
}
b, err := ioutil.ReadFile(noncefile)
if err != nil {
return nil, err
}
_, err = socket.Write(b)
if err != nil {
return nil, err
}
return NewConn(socket)
}

View File

@ -1,5 +1,3 @@
//+build !windows
package dbus package dbus
import ( import (

View File

@ -31,6 +31,7 @@ func (o *oobReader) Read(b []byte) (n int, err error) {
type unixTransport struct { type unixTransport struct {
*net.UnixConn *net.UnixConn
rdr *oobReader
hasUnixFDs bool hasUnixFDs bool
} }
@ -79,10 +80,15 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
// To be sure that all bytes of out-of-band data are read, we use a special // To be sure that all bytes of out-of-band data are read, we use a special
// reader that uses ReadUnix on the underlying connection instead of Read // reader that uses ReadUnix on the underlying connection instead of Read
// and gathers the out-of-band data in a buffer. // and gathers the out-of-band data in a buffer.
rd := &oobReader{conn: t.UnixConn} if t.rdr == nil {
t.rdr = &oobReader{conn: t.UnixConn}
} else {
t.rdr.oob = nil
}
// read the first 16 bytes (the part of the header that has a constant size), // read the first 16 bytes (the part of the header that has a constant size),
// from which we can figure out the length of the rest of the message // from which we can figure out the length of the rest of the message
if _, err := io.ReadFull(rd, csheader[:]); err != nil { if _, err := io.ReadFull(t.rdr, csheader[:]); err != nil {
return nil, err return nil, err
} }
switch csheader[0] { switch csheader[0] {
@ -104,7 +110,7 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
// decode headers and look for unix fds // decode headers and look for unix fds
headerdata := make([]byte, hlen+4) headerdata := make([]byte, hlen+4)
copy(headerdata, csheader[12:]) copy(headerdata, csheader[12:])
if _, err := io.ReadFull(t, headerdata[4:]); err != nil { if _, err := io.ReadFull(t.rdr, headerdata[4:]); err != nil {
return nil, err return nil, err
} }
dec := newDecoder(bytes.NewBuffer(headerdata), order) dec := newDecoder(bytes.NewBuffer(headerdata), order)
@ -122,7 +128,7 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
all := make([]byte, 16+hlen+blen) all := make([]byte, 16+hlen+blen)
copy(all, csheader[:]) copy(all, csheader[:])
copy(all[16:], headerdata[4:]) copy(all[16:], headerdata[4:])
if _, err := io.ReadFull(rd, all[16+hlen:]); err != nil { if _, err := io.ReadFull(t.rdr, all[16+hlen:]); err != nil {
return nil, err return nil, err
} }
if unixfds != 0 { if unixfds != 0 {
@ -130,7 +136,7 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
return nil, errors.New("dbus: got unix fds on unsupported transport") return nil, errors.New("dbus: got unix fds on unsupported transport")
} }
// read the fds from the OOB data // read the fds from the OOB data
scms, err := syscall.ParseSocketControlMessage(rd.oob) scms, err := syscall.ParseSocketControlMessage(t.rdr.oob)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -148,11 +154,23 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
// substitute the values in the message body (which are indices for the // substitute the values in the message body (which are indices for the
// array receiver via OOB) with the actual values // array receiver via OOB) with the actual values
for i, v := range msg.Body { for i, v := range msg.Body {
if j, ok := v.(UnixFDIndex); ok { switch v.(type) {
case UnixFDIndex:
j := v.(UnixFDIndex)
if uint32(j) >= unixfds { if uint32(j) >= unixfds {
return nil, InvalidMessageError("invalid index for unix fd") return nil, InvalidMessageError("invalid index for unix fd")
} }
msg.Body[i] = UnixFD(fds[j]) msg.Body[i] = UnixFD(fds[j])
case []UnixFDIndex:
idxArray := v.([]UnixFDIndex)
fdArray := make([]UnixFD, len(idxArray))
for k, j := range idxArray {
if uint32(j) >= unixfds {
return nil, InvalidMessageError("invalid index for unix fd")
}
fdArray[k] = UnixFD(fds[j])
}
msg.Body[i] = fdArray
} }
} }
return msg, nil return msg, nil
@ -185,7 +203,7 @@ func (t *unixTransport) SendMessage(msg *Message) error {
} }
} else { } else {
if err := msg.EncodeTo(t, nativeEndian); err != nil { if err := msg.EncodeTo(t, nativeEndian); err != nil {
return nil return err
} }
} }
return nil return nil

View File

@ -26,7 +26,7 @@ func MakeVariantWithSignature(v interface{}, s Signature) Variant {
} }
// ParseVariant parses the given string as a variant as described at // ParseVariant parses the given string as a variant as described at
// https://developer.gnome.org/glib/unstable/gvariant-text.html. If sig is not // https://developer.gnome.org/glib/stable/gvariant-text.html. If sig is not
// empty, it is taken to be the expected signature for the variant. // empty, it is taken to be the expected signature for the variant.
func ParseVariant(s string, sig Signature) (Variant, error) { func ParseVariant(s string, sig Signature) (Variant, error) {
tokens := varLex(s) tokens := varLex(s)
@ -129,7 +129,7 @@ func (v Variant) Signature() Signature {
} }
// String returns the string representation of the underlying value of v as // String returns the string representation of the underlying value of v as
// described at https://developer.gnome.org/glib/unstable/gvariant-text.html. // described at https://developer.gnome.org/glib/stable/gvariant-text.html.
func (v Variant) String() string { func (v Variant) String() string {
s, unamb := v.format() s, unamb := v.format()
if !unamb { if !unamb {

View File

@ -51,7 +51,7 @@ func varLex(s string) []varToken {
} }
func (l *varLexer) accept(valid string) bool { func (l *varLexer) accept(valid string) bool {
if strings.IndexRune(valid, l.next()) >= 0 { if strings.ContainsRune(valid, l.next()) {
return true return true
} }
l.backup() l.backup()
@ -214,17 +214,17 @@ func varLexNumber(l *varLexer) lexState {
digits = "01234567" digits = "01234567"
} }
} }
for strings.IndexRune(digits, l.next()) >= 0 { for strings.ContainsRune(digits, l.next()) {
} }
l.backup() l.backup()
if l.accept(".") { if l.accept(".") {
for strings.IndexRune(digits, l.next()) >= 0 { for strings.ContainsRune(digits, l.next()) {
} }
l.backup() l.backup()
} }
if l.accept("eE") { if l.accept("eE") {
l.accept("+-") l.accept("+-")
for strings.IndexRune("0123456789", l.next()) >= 0 { for strings.ContainsRune("0123456789", l.next()) {
} }
l.backup() l.backup()
} }

8
vendor/modules.txt vendored
View File

@ -44,9 +44,9 @@ github.com/containernetworking/cni/pkg/version
# github.com/coreos/go-iptables v0.5.0 # github.com/coreos/go-iptables v0.5.0
## explicit ## explicit
github.com/coreos/go-iptables/iptables github.com/coreos/go-iptables/iptables
# github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 # github.com/coreos/go-systemd/v22 v22.2.0
## explicit ## explicit
github.com/coreos/go-systemd/activation github.com/coreos/go-systemd/v22/activation
# github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c # github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c
## explicit ## explicit
github.com/d2g/dhcp4 github.com/d2g/dhcp4
@ -62,9 +62,9 @@ github.com/d2g/dhcp4server/leasepool/memorypool
## explicit ## explicit
# github.com/fsnotify/fsnotify v1.4.9 # github.com/fsnotify/fsnotify v1.4.9
github.com/fsnotify/fsnotify github.com/fsnotify/fsnotify
# github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c # github.com/godbus/dbus/v5 v5.0.3
## explicit ## explicit
github.com/godbus/dbus github.com/godbus/dbus/v5
# github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56 # github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56
## explicit ## explicit
github.com/j-keck/arping github.com/j-keck/arping