diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-03-25 05:26:37 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-03-25 05:26:37 +0900 |
| commit | 61dbfeffe77df9c1a11413b3cb8954933e79b45f (patch) | |
| tree | 7f7f6bde9a8662848ad9392621316cbbc454a9f0 /wl/conn.go | |
| parent | 532feb4bfaa84a57dc8de97f36b13a89610a0584 (diff) | |
sandbox/wl: move into sandbox
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'wl/conn.go')
| -rw-r--r-- | wl/conn.go | 121 |
1 files changed, 0 insertions, 121 deletions
diff --git a/wl/conn.go b/wl/conn.go deleted file mode 100644 index 9baa5abe..00000000 --- a/wl/conn.go +++ /dev/null @@ -1,121 +0,0 @@ -// Package wl implements Wayland security_context_v1 protocol. -package wl - -import ( - "errors" - "net" - "os" - "runtime" - "sync" - "syscall" -) - -type Conn struct { - conn *net.UnixConn - - done chan struct{} - doneOnce sync.Once - - mu sync.Mutex -} - -// Attach connects Conn to a wayland socket. -func (c *Conn) Attach(p string) (err error) { - c.mu.Lock() - defer c.mu.Unlock() - - if c.conn != nil { - return errors.New("attached") - } - - c.conn, err = net.DialUnix("unix", nil, &net.UnixAddr{Name: p, Net: "unix"}) - return -} - -// Close releases resources and closes the connection to the wayland compositor. -func (c *Conn) Close() error { - c.mu.Lock() - defer c.mu.Unlock() - - if c.done == nil { - return errors.New("no socket bound") - } - - c.doneOnce.Do(func() { - c.done <- struct{}{} - <-c.done - }) - - // closed by wayland - runtime.SetFinalizer(c.conn, nil) - return nil -} - -func (c *Conn) Bind(p, appID, instanceID string) (*os.File, error) { - c.mu.Lock() - defer c.mu.Unlock() - - if c.conn == nil { - return nil, errors.New("not attached") - } - if c.done != nil { - return nil, errors.New("bound") - } - - if rc, err := c.conn.SyscallConn(); err != nil { - // unreachable - return nil, err - } else { - c.done = make(chan struct{}) - return bindRawConn(c.done, rc, p, appID, instanceID) - } -} - -func bindRawConn(done chan struct{}, rc syscall.RawConn, p, appID, instanceID string) (*os.File, error) { - var syncPipe [2]*os.File - - if r, w, err := os.Pipe(); err != nil { - return nil, err - } else { - syncPipe[0] = r - syncPipe[1] = w - } - - setupDone := make(chan error, 1) // does not block with c.done - - go func() { - if err := rc.Control(func(fd uintptr) { - // prevent runtime from closing the read end of sync fd - runtime.SetFinalizer(syncPipe[0], nil) - - // allow the Bind method to return after setup - setupDone <- bind(fd, p, appID, instanceID, syncPipe[0].Fd()) - close(setupDone) - - // keep socket alive until done is requested - <-done - runtime.KeepAlive(syncPipe[1]) - }); err != nil { - setupDone <- err - } - - // notify Close that rc.Control has returned - close(done) - }() - - // return write end of the pipe - return syncPipe[1], <-setupDone -} - -func bind(fd uintptr, p, appID, instanceID string, syncFd uintptr) error { - // ensure p is available - if f, err := os.Create(p); err != nil { - return err - } else if err = f.Close(); err != nil { - return err - } else if err = os.Remove(p); err != nil { - return err - } - - return bindWaylandFd(p, fd, appID, instanceID, syncFd) -} |
