diff options
| author | Ophestra Umiker <cat@ophivana.moe> | 2024-09-09 03:11:50 +0900 |
|---|---|---|
| committer | Ophestra Umiker <cat@ophivana.moe> | 2024-09-09 03:11:50 +0900 |
| commit | 357cc4ce4d2888033a8163fe39861c8a88301da6 (patch) | |
| tree | a6dbdd09fc5ef2dea82ad1c85627b6455c2f3477 /dbus/setup.go | |
| parent | 3242ce340621839d03ecf34bb3ed20d7c6f3cbb3 (diff) | |
dbus: implement xdg-dbus-proxy wrapper
Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
Diffstat (limited to 'dbus/setup.go')
| -rw-r--r-- | dbus/setup.go | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/dbus/setup.go b/dbus/setup.go new file mode 100644 index 00000000..8fb7b1b5 --- /dev/null +++ b/dbus/setup.go @@ -0,0 +1,73 @@ +package dbus + +import ( + "errors" + "os" + "os/exec" + "strings" + "sync" +) + +// Proxy holds references to a xdg-dbus-proxy process, and should never be copied. +// Once sealed, configuration changes will no longer be possible and attempting to do so will result in a panic. +type Proxy struct { + cmd *exec.Cmd + + statP [2]*os.File + argsP [2]*os.File + + address [2]string + path string + + wait *chan error + read *chan error + ready *chan bool + + seal *string + lock sync.RWMutex +} + +func (p *Proxy) String() string { + if p.cmd != nil { + return p.cmd.String() + } + + if p.seal != nil { + return *p.seal + } + + return "(unsealed dbus proxy)" +} + +// Seal seals the Proxy instance. +func (p *Proxy) Seal(c *Config) error { + p.lock.Lock() + defer p.lock.Unlock() + + if p.seal != nil { + panic("dbus proxy sealed twice") + } + args := c.Args(p.address[0], p.address[1]) + + seal := strings.Builder{} + for _, arg := range args { + // reject argument strings containing null + for _, b := range arg { + if b == '\x00' { + return errors.New("argument contains null") + } + } + + // write null terminated argument + seal.WriteString(arg) + seal.WriteByte('\x00') + } + v := seal.String() + p.seal = &v + return nil +} + +// New returns a reference to a new unsealed Proxy. +func New(binPath, address, path string) *Proxy { + return &Proxy{path: binPath, address: [2]string{address, path}} +} |
