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 95f1612e4e43d0f052f7730f1f3d5e6d5139ec28
Author: [email protected] <[email protected]>
AuthorDate: Sun Jun 7 22:58:38 2026 -0600

    feat(e_wl_proxy): per-client connection with Ecore fd handlers
    
    Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
---
 src/bin/e_wl_proxy/e_wl_proxy.h      |   8 +++
 src/bin/e_wl_proxy/e_wl_proxy_conn.c | 120 +++++++++++++++++++++++++++++++++++
 2 files changed, 128 insertions(+)

diff --git a/src/bin/e_wl_proxy/e_wl_proxy.h b/src/bin/e_wl_proxy/e_wl_proxy.h
index 53e3a4b12..a468f245a 100644
--- a/src/bin/e_wl_proxy/e_wl_proxy.h
+++ b/src/bin/e_wl_proxy/e_wl_proxy.h
@@ -47,4 +47,12 @@ int e_wl_proxy_pipe_flush(int to, E_Wl_Proxy_Pipe *pipe);
  * (len == 0) on entry — call e_wl_proxy_pipe_flush() first if it is not. */
 ssize_t e_wl_proxy_forward(int from, int to, E_Wl_Proxy_Pipe *pipe);
 
+/* ---- per-client connection (e_wl_proxy_conn.c) ---- */
+typedef struct _E_Wl_Proxy_Conn E_Wl_Proxy_Conn;
+
+/* Take an accepted client fd, connect upstream to <backend>, and start
+ * forwarding both ways. Returns NULL (and closes client_fd) on failure. */
+E_Wl_Proxy_Conn *e_wl_proxy_conn_add(int client_fd, const char *backend);
+void             e_wl_proxy_conn_del(E_Wl_Proxy_Conn *conn);
+
 #endif
diff --git a/src/bin/e_wl_proxy/e_wl_proxy_conn.c b/src/bin/e_wl_proxy/e_wl_proxy_conn.c
new file mode 100644
index 000000000..caa9df614
--- /dev/null
+++ b/src/bin/e_wl_proxy/e_wl_proxy_conn.c
@@ -0,0 +1,120 @@
+#include "config.h"
+#include "e_wl_proxy.h"
+#include <Ecore.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+struct _E_Wl_Proxy_Conn
+{
+   int client_fd;
+   int backend_fd;
+   Ecore_Fd_Handler *client_h;
+   Ecore_Fd_Handler *backend_h;
+   E_Wl_Proxy_Pipe to_backend;   /* client -> backend */
+   E_Wl_Proxy_Pipe to_client;    /* backend -> client */
+};
+
+static void
+_conn_update_flags(E_Wl_Proxy_Conn *conn)
+{
+   /* watch for writable only while a direction has buffered output */
+   int cf = ECORE_FD_READ | ECORE_FD_ERROR;
+   int bf = ECORE_FD_READ | ECORE_FD_ERROR;
+
+   if (conn->to_client.len > 0)  cf |= ECORE_FD_WRITE;  /* flush toward client */
+   if (conn->to_backend.len > 0) bf |= ECORE_FD_WRITE;  /* flush toward backend */
+
+   ecore_main_fd_handler_active_set(conn->client_h, cf);
+   ecore_main_fd_handler_active_set(conn->backend_h, bf);
+}
+
+static Eina_Bool
+_conn_client_cb(void *data, Ecore_Fd_Handler *fdh)
+{
+   E_Wl_Proxy_Conn *conn = data;
+
+   if (ecore_main_fd_handler_active_get(fdh, ECORE_FD_ERROR)) goto dead;
+
+   /* finish flushing anything queued toward the client */
+   if (conn->to_client.len > 0)
+     {
+        int r = e_wl_proxy_pipe_flush(conn->client_fd, &conn->to_client);
+        if (r < 0) goto dead;
+     }
+   /* read client -> forward to backend (only if that direction is drained) */
+   if (conn->to_backend.len == 0 &&
+       ecore_main_fd_handler_active_get(fdh, ECORE_FD_READ))
+     {
+        ssize_t n = e_wl_proxy_forward(conn->client_fd, conn->backend_fd,
+                                       &conn->to_backend);
+        if (n < 0) goto dead;
+     }
+
+   _conn_update_flags(conn);
+   return ECORE_CALLBACK_RENEW;
+
+dead:
+   e_wl_proxy_conn_del(conn);
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool
+_conn_backend_cb(void *data, Ecore_Fd_Handler *fdh)
+{
+   E_Wl_Proxy_Conn *conn = data;
+
+   if (ecore_main_fd_handler_active_get(fdh, ECORE_FD_ERROR)) goto dead;
+
+   if (conn->to_backend.len > 0)
+     {
+        int r = e_wl_proxy_pipe_flush(conn->backend_fd, &conn->to_backend);
+        if (r < 0) goto dead;
+     }
+   if (conn->to_client.len == 0 &&
+       ecore_main_fd_handler_active_get(fdh, ECORE_FD_READ))
+     {
+        ssize_t n = e_wl_proxy_forward(conn->backend_fd, conn->client_fd,
+                                       &conn->to_client);
+        if (n < 0) goto dead;
+     }
+
+   _conn_update_flags(conn);
+   return ECORE_CALLBACK_RENEW;
+
+dead:
+   e_wl_proxy_conn_del(conn);
+   return ECORE_CALLBACK_CANCEL;
+}
+
+E_Wl_Proxy_Conn *
+e_wl_proxy_conn_add(int client_fd, const char *backend)
+{
+   E_Wl_Proxy_Conn *conn;
+
+   conn = calloc(1, sizeof(*conn));
+   if (!conn) { close(client_fd); return NULL; }
+
+   conn->client_fd = client_fd;
+   conn->backend_fd = e_wl_proxy_connect(backend);
+   if (conn->backend_fd < 0) { close(client_fd); free(conn); return NULL; }
+
+   conn->client_h = ecore_main_fd_handler_add(
+      conn->client_fd, ECORE_FD_READ | ECORE_FD_ERROR, _conn_client_cb, conn, NULL, NULL);
+   conn->backend_h = ecore_main_fd_handler_add(
+      conn->backend_fd, ECORE_FD_READ | ECORE_FD_ERROR, _conn_backend_cb, conn, NULL, NULL);
+
+   if (!conn->client_h || !conn->backend_h) { e_wl_proxy_conn_del(conn); return NULL; }
+
+   return conn;
+}
+
+void
+e_wl_proxy_conn_del(E_Wl_Proxy_Conn *conn)
+{
+   if (!conn) return;
+   if (conn->client_h)  ecore_main_fd_handler_del(conn->client_h);
+   if (conn->backend_h) ecore_main_fd_handler_del(conn->backend_h);
+   if (conn->client_fd >= 0)  close(conn->client_fd);
+   if (conn->backend_fd >= 0) close(conn->backend_fd);
+   free(conn);
+}

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to