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 a215803548ccf33fc95a58647fd661f86088a2cb
Author: [email protected] <[email protected]>
AuthorDate: Sun Jun 7 22:50:32 2026 -0600

    feat(e_wl_proxy): read+forward chunk with fd capture and buffering
    
    Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
---
 src/bin/e_wl_proxy/e_wl_proxy_pipe.c       | 57 +++++++++++++++++++++++++++++-
 src/bin/e_wl_proxy/tests/e_wl_proxy_test.c | 53 +++++++++++++++++++++++++++
 2 files changed, 109 insertions(+), 1 deletion(-)

diff --git a/src/bin/e_wl_proxy/e_wl_proxy_pipe.c b/src/bin/e_wl_proxy/e_wl_proxy_pipe.c
index 3e143b8d6..e7435c04b 100644
--- a/src/bin/e_wl_proxy/e_wl_proxy_pipe.c
+++ b/src/bin/e_wl_proxy/e_wl_proxy_pipe.c
@@ -63,4 +63,59 @@ e_wl_proxy_pipe_flush(int to, E_Wl_Proxy_Pipe *pipe)
    return 0;
 }
 
-ssize_t e_wl_proxy_forward(int from, int to, E_Wl_Proxy_Pipe *pipe) { (void)from; (void)to; (void)pipe; return -1; }
+ssize_t
+e_wl_proxy_forward(int from, int to, E_Wl_Proxy_Pipe *pipe)
+{
+   struct iovec iov;
+   struct msghdr msg;
+   union {
+      struct cmsghdr align;
+      char buf[CMSG_SPACE(E_WL_PROXY_MAX_FDS * sizeof(int))];
+   } cmsgbuf;
+   struct cmsghdr *c;
+   ssize_t n;
+
+   /* caller guarantees the pipe is drained before reading more */
+   if (pipe->len != 0) return 0;
+
+   iov.iov_base = pipe->buf;
+   iov.iov_len = sizeof(pipe->buf);
+
+   memset(&msg, 0, sizeof(msg));
+   msg.msg_iov = &iov;
+   msg.msg_iovlen = 1;
+   msg.msg_control = cmsgbuf.buf;
+   msg.msg_controllen = sizeof(cmsgbuf.buf);
+
+   do {
+        n = recvmsg(from, &msg, MSG_CMSG_CLOEXEC);
+   } while (n < 0 && errno == EINTR);
+
+   if (n == 0) return -1;                 /* EOF */
+   if (n < 0)
+     {
+        if (errno == EAGAIN || errno == EWOULDBLOCK) return 0;
+        return -1;
+     }
+
+   /* collect any fds that arrived with this chunk */
+   pipe->nfds = 0;
+   for (c = CMSG_FIRSTHDR(&msg); c; c = CMSG_NXTHDR(&msg, c))
+     {
+        if (c->cmsg_level == SOL_SOCKET && c->cmsg_type == SCM_RIGHTS)
+          {
+             int cnt = (c->cmsg_len - CMSG_LEN(0)) / sizeof(int);
+             int i;
+             for (i = 0; i < cnt && pipe->nfds < E_WL_PROXY_MAX_FDS; i++)
+               memcpy(&pipe->fds[pipe->nfds++], CMSG_DATA(c) + i * sizeof(int), sizeof(int));
+          }
+     }
+
+   pipe->len = (int)n;
+   pipe->off = 0;
+
+   /* push it out now; any unsent remainder stays buffered for the writable cb */
+   if (e_wl_proxy_pipe_flush(to, pipe) < 0) return -1;
+
+   return n;
+}
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 fef8d5e19..876c8f4bf 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
@@ -105,6 +105,58 @@ test_pipe_flush_bytes_and_fd(void)
    close(sp[0]); close(sp[1]);
 }
 
+/* end-to-end: write into `from`, forward to a second socketpair, read out */
+static void
+test_forward_roundtrip(void)
+{
+   int a[2], b[2];   /* a: client<->proxy_in ; b: proxy_out<->upstream */
+   CHECK(socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, a) == 0);
+   CHECK(socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, b) == 0);
+
+   /* client sends "ping" + an fd */
+   int marker[2];
+   CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, marker) == 0);
+   CHECK(write(marker[0], "Q", 1) == 1);
+
+   struct iovec iov = { "ping", 4 };
+   union { struct cmsghdr h; char b[CMSG_SPACE(sizeof(int))]; } cm;
+   struct msghdr msg = {0};
+   msg.msg_iov = &iov; msg.msg_iovlen = 1;
+   msg.msg_control = cm.b; msg.msg_controllen = sizeof(cm.b);
+   struct cmsghdr *c = CMSG_FIRSTHDR(&msg);
+   c->cmsg_level = SOL_SOCKET; c->cmsg_type = SCM_RIGHTS; c->cmsg_len = CMSG_LEN(sizeof(int));
+   int sendfd = marker[1];
+   memcpy(CMSG_DATA(c), &sendfd, sizeof(int));
+   CHECK(sendmsg(a[0], &msg, 0) == 4);
+
+   /* proxy forwards a[1] -> b[0] */
+   E_Wl_Proxy_Pipe pipe;
+   memset(&pipe, 0, sizeof(pipe));
+   CHECK(e_wl_proxy_forward(a[1], b[0], &pipe) == 4);
+   CHECK(pipe.len == 0);
+
+   /* upstream reads "ping" + fd from b[1] */
+   char rb[8] = {0};
+   struct iovec riov = { rb, sizeof(rb) };
+   union { struct cmsghdr h; char b[CMSG_SPACE(sizeof(int))]; } rcm;
+   struct msghdr rmsg = {0};
+   rmsg.msg_iov = &riov; rmsg.msg_iovlen = 1;
+   rmsg.msg_control = rcm.b; rmsg.msg_controllen = sizeof(rcm.b);
+   CHECK(recvmsg(b[1], &rmsg, 0) == 4);
+   CHECK(memcmp(rb, "ping", 4) == 0);
+   struct cmsghdr *rc = CMSG_FIRSTHDR(&rmsg);
+   CHECK(rc != NULL && rc->cmsg_type == SCM_RIGHTS);
+   int got = -1; memcpy(&got, CMSG_DATA(rc), sizeof(int));
+   char q = 0; CHECK(read(got, &q, 1) == 1 && q == 'Q');
+
+   /* EOF propagation: close client end, forward returns -1 */
+   close(a[0]);
+   CHECK(e_wl_proxy_forward(a[1], b[0], &pipe) == -1);
+
+   close(got); close(marker[0]); close(marker[1]);
+   close(a[1]); close(b[0]); close(b[1]);
+}
+
 int
 main(void)
 {
@@ -112,6 +164,7 @@ main(void)
    test_socket_path();
    test_listen_and_connect();
    test_pipe_flush_bytes_and_fd();
+   test_forward_roundtrip();
    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.

Reply via email to