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.