aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/wayland
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-11-15 23:20:03 +0900
committerOphestra <cat@gensokyo.uk>2025-11-15 23:25:46 +0900
commitfe40af7b7e95356b7d88e35941097edc9700f093 (patch)
treed04ddc46f4cf053e51156e1c08cdeaf16dd2a2fa /internal/wayland
parent12751932d1cbfc911a75445061d87264b927de5f (diff)
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 <cat@gensokyo.uk>
Diffstat (limited to 'internal/wayland')
-rw-r--r--internal/wayland/conn.go87
-rw-r--r--internal/wayland/wayland-client-helper.c4
-rw-r--r--internal/wayland/wayland-client-helper.h2
3 files changed, 9 insertions, 84 deletions
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);