From 61972d61f650be2fb86eb2ead452b74c02b3e00f Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sun, 16 Nov 2025 01:23:16 +0900 Subject: internal/wayland: reimplement connect/bind code The old implementation is relocated to system/wayland/deprecated.go. Signed-off-by: Ophestra --- system/wayland/deprecated.go | 47 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) (limited to 'system') diff --git a/system/wayland/deprecated.go b/system/wayland/deprecated.go index e544597e..3eddbf73 100644 --- a/system/wayland/deprecated.go +++ b/system/wayland/deprecated.go @@ -15,6 +15,9 @@ import ( "hakurei.app/internal/wayland" ) +//go:linkname bindWaylandFd hakurei.app/internal/wayland.bindWaylandFd +func bindWaylandFd(socketPath string, fd uintptr, appID, instanceID string, syncFd uintptr) error + // Conn represents a connection to the wayland display server. // // Deprecated: this interface is being replaced. @@ -60,9 +63,6 @@ func (c *Conn) Close() error { return nil } -//go:linkname bindRawConn hakurei.app/internal/wayland.bindRawConn -func bindRawConn(done chan struct{}, rc syscall.RawConn, p, appID, instanceID string) ([2]int, error) - // Bind binds the new socket to pathname. func (c *Conn) Bind(pathname, appID, instanceID string) (*os.File, error) { c.mu.Lock() @@ -88,6 +88,47 @@ func (c *Conn) Bind(pathname, appID, instanceID string) (*os.File, error) { } } +func bindRawConn(done chan struct{}, rc syscall.RawConn, p, appID, instanceID string) ([2]int, error) { + var closeFds [2]int + if err := syscall.Pipe2(closeFds[0:], syscall.O_CLOEXEC); err != nil { + return closeFds, err + } + + setupDone := make(chan error, 1) // does not block with c.done + + go func() { + if err := rc.Control(func(fd uintptr) { + // allow the Bind method to return after setup + setupDone <- bind(fd, p, appID, instanceID, uintptr(closeFds[1])) + close(setupDone) + + // keep socket alive until done is requested + <-done + }); err != nil { + setupDone <- err + } + + // notify Close that rc.Control has returned + close(done) + }() + + // return write end of the pipe + return closeFds, <-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) +} + const ( // WaylandDisplay contains the name of the server socket // (https://gitlab.freedesktop.org/wayland/wayland/-/blob/1.23.1/src/wayland-client.c#L1147) -- cgit v1.3.1