From fe40af7b7e95356b7d88e35941097edc9700f093 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sat, 15 Nov 2025 23:20:03 +0900 Subject: internal/wayland: relocate connection struct This interface is getting replaced, so relocating it to the deprecated wrapper package before working on its replacement. Signed-off-by: Ophestra --- internal/wayland/conn.go | 87 +++----------------------------- internal/wayland/wayland-client-helper.c | 4 +- internal/wayland/wayland-client-helper.h | 2 +- 3 files changed, 9 insertions(+), 84 deletions(-) (limited to 'internal/wayland') diff --git a/internal/wayland/conn.go b/internal/wayland/conn.go index c55fe704..addbc0d3 100644 --- a/internal/wayland/conn.go +++ b/internal/wayland/conn.go @@ -1,101 +1,26 @@ package wayland import ( - "errors" - "net" "os" - "runtime" - "sync" "syscall" ) -// Conn represents a connection to the wayland display server. -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("socket already 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 -} - -// Bind binds the new socket to pathname. -func (c *Conn) Bind(pathname, appID, instanceID string) (*os.File, error) { - c.mu.Lock() - defer c.mu.Unlock() - - if c.conn == nil { - return nil, errors.New("socket not attached") - } - if c.done != nil { - return nil, errors.New("socket already bound") - } - - if rc, err := c.conn.SyscallConn(); err != nil { - // unreachable - return nil, err - } else { - c.done = make(chan struct{}) - return bindRawConn(c.done, rc, pathname, 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 +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) { - // 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()) + setupDone <- bind(fd, p, appID, instanceID, uintptr(closeFds[1])) close(setupDone) // keep socket alive until done is requested <-done - runtime.KeepAlive(syncPipe[1]) }); err != nil { setupDone <- err } @@ -105,7 +30,7 @@ func bindRawConn(done chan struct{}, rc syscall.RawConn, p, appID, instanceID st }() // return write end of the pipe - return syncPipe[1], <-setupDone + return closeFds, <-setupDone } func bind(fd uintptr, p, appID, instanceID string, syncFd uintptr) error { diff --git a/internal/wayland/wayland-client-helper.c b/internal/wayland/wayland-client-helper.c index a6a824b5..ccfbaf6c 100644 --- a/internal/wayland/wayland-client-helper.c +++ b/internal/wayland/wayland-client-helper.c @@ -36,7 +36,7 @@ hakurei_wayland_res hakurei_bind_wayland_fd( int fd, const char *app_id, const char *instance_id, - int sync_fd) { + int close_fd) { hakurei_wayland_res res = HAKUREI_WAYLAND_SUCCESS; /* see wayland.go for handling */ struct wl_display *display = NULL; @@ -88,7 +88,7 @@ hakurei_wayland_res hakurei_bind_wayland_fd( goto out; } - security_context = wp_security_context_manager_v1_create_listener(security_context_manager, listen_fd, sync_fd); + security_context = wp_security_context_manager_v1_create_listener(security_context_manager, listen_fd, close_fd); if (security_context == NULL) { /* not reached */ res = HAKUREI_WAYLAND_NOT_AVAIL; goto out; diff --git a/internal/wayland/wayland-client-helper.h b/internal/wayland/wayland-client-helper.h index dc456c31..9dd7c901 100644 --- a/internal/wayland/wayland-client-helper.h +++ b/internal/wayland/wayland-client-helper.h @@ -21,4 +21,4 @@ hakurei_wayland_res hakurei_bind_wayland_fd( int fd, const char *app_id, const char *instance_id, - int sync_fd); + int close_fd); -- cgit v1.3.1