This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch feat/e-wl-proxy-planb
in repository enlightenment.
View the commit online.
commit cf3fc9afa9febc45695c05a3d7840dd114db1e2a
Author: [email protected] <[email protected]>
AuthorDate: Sun Jun 7 22:46:56 2026 -0600
feat(e_wl_proxy): listening socket with lock + connect helper
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
---
src/bin/e_wl_proxy/e_wl_proxy_socket.c | 78 +++++++++++++++++++++++++++++-
src/bin/e_wl_proxy/tests/e_wl_proxy_test.c | 31 ++++++++++++
2 files changed, 107 insertions(+), 2 deletions(-)
diff --git a/src/bin/e_wl_proxy/e_wl_proxy_socket.c b/src/bin/e_wl_proxy/e_wl_proxy_socket.c
index 5d4ba9580..a52b7f66e 100644
--- a/src/bin/e_wl_proxy/e_wl_proxy_socket.c
+++ b/src/bin/e_wl_proxy/e_wl_proxy_socket.c
@@ -3,6 +3,12 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/file.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
int
e_wl_proxy_socket_path(const char *name, char *buf, size_t buflen)
@@ -21,5 +27,73 @@ e_wl_proxy_socket_path(const char *name, char *buf, size_t buflen)
return 0;
}
-int e_wl_proxy_listen(const char *name) { (void)name; return -1; }
-int e_wl_proxy_connect(const char *name) { (void)name; return -1; }
+static int
+_fill_addr(const char *name, struct sockaddr_un *addr)
+{
+ char path[256];
+
+ if (e_wl_proxy_socket_path(name, path, sizeof(path)) < 0) return -1;
+ if (strlen(path) >= sizeof(addr->sun_path)) return -1;
+
+ memset(addr, 0, sizeof(*addr));
+ addr->sun_family = AF_UNIX;
+ strcpy(addr->sun_path, path);
+ return 0;
+}
+
+int
+e_wl_proxy_listen(const char *name)
+{
+ struct sockaddr_un addr;
+ char lockpath[256 + 8];
+ char path[256];
+ int fd, lock;
+
+ if (e_wl_proxy_socket_path(name, path, sizeof(path)) < 0) return -1;
+ if (_fill_addr(name, &addr) < 0) return -1;
+
+ /* take "<path>.lock" so two servers can't share the name */
+ snprintf(lockpath, sizeof(lockpath), "%s.lock", path);
+ lock = open(lockpath, O_CREAT | O_CLOEXEC, 0660);
+ if (lock < 0) return -1;
+ if (flock(lock, LOCK_EX | LOCK_NB) < 0) { close(lock); return -1; }
+
+ /* a leftover socket from a crash is safe to remove now we hold the lock */
+ unlink(path);
+
+ fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
+ if (fd < 0) { close(lock); return -1; }
+
+ if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) goto err;
+ if (listen(fd, 128) < 0) goto err;
+
+ /* intentionally leak `lock`: it must stay open for the socket's lifetime.
+ * The process exit releases it. */
+ return fd;
+
+err:
+ close(fd);
+ close(lock);
+ return -1;
+}
+
+int
+e_wl_proxy_connect(const char *name)
+{
+ struct sockaddr_un addr;
+ int fd;
+
+ if (_fill_addr(name, &addr) < 0) return -1;
+
+ fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
+ if (fd < 0) return -1;
+
+ if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+ {
+ if (errno != EINPROGRESS) { close(fd); return -1; }
+ /* nonblocking connect in progress: fine for a unix socket, it
+ * completes effectively immediately; caller treats it as connected. */
+ }
+
+ return fd;
+}
diff --git a/src/bin/e_wl_proxy/tests/e_wl_proxy_test.c b/src/bin/e_wl_proxy/tests/e_wl_proxy_test.c
index 9616a8748..491298dcd 100644
--- a/src/bin/e_wl_proxy/tests/e_wl_proxy_test.c
+++ b/src/bin/e_wl_proxy/tests/e_wl_proxy_test.c
@@ -2,6 +2,9 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
static int failures = 0;
@@ -28,11 +31,39 @@ test_socket_path(void)
CHECK(e_wl_proxy_socket_path("wayland-0", buf, 8) == -1);
}
+static void
+test_listen_and_connect(void)
+{
+ char tmpl[] = "/tmp/ewlpXXXXXX";
+ char *dir = mkdtemp(tmpl);
+ CHECK(dir != NULL);
+ setenv("XDG_RUNTIME_DIR", dir, 1);
+
+ int lfd = e_wl_proxy_listen("wayland-test");
+ CHECK(lfd >= 0);
+
+ /* a second listen on the same name must fail (lock held) */
+ int lfd2 = e_wl_proxy_listen("wayland-test");
+ CHECK(lfd2 == -1);
+
+ /* a plain client can connect */
+ int cfd = e_wl_proxy_connect("wayland-test");
+ CHECK(cfd >= 0);
+
+ int afd = accept(lfd, NULL, NULL);
+ CHECK(afd >= 0);
+
+ if (afd >= 0) close(afd);
+ if (cfd >= 0) close(cfd);
+ if (lfd >= 0) close(lfd);
+}
+
int
main(void)
{
test_harness_runs();
test_socket_path();
+ test_listen_and_connect();
if (failures) { fprintf(stderr, "%d check(s) failed\n", failures); return 1; }
printf("all checks passed\n");
return 0;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.