]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
feat: socket poll support — wire ksocket_poll into sock_fops
authorTulio A M Mendes <[email protected]>
Fri, 13 Feb 2026 23:52:38 +0000 (20:52 -0300)
committerTulio A M Mendes <[email protected]>
Fri, 13 Feb 2026 23:52:38 +0000 (20:52 -0300)
poll()/select() now works correctly on socket file descriptors.

- socket.c: added ksocket_poll() that checks socket readiness based
  on state (CONNECTED/LISTENING/PEER_CLOSED), rx_count, aq_count,
  and error flag; returns VFS_POLL_IN/OUT/ERR/HUP as appropriate
- socket.h: declared ksocket_poll()
- syscall.c: added sock_node_poll() wrapper and wired .poll into
  sock_fops — sockets now participate in the generic f_ops->poll
  dispatch path in poll_wait_kfds

Previously socket fds in poll/select silently reported ready via
the fallback path. Now they report actual readiness.

20/20 smoke tests pass.

include/socket.h
src/kernel/socket.c
src/kernel/syscall.c

index 327f910eb6951795bbcf2df81830dfa25a013a1f..ab06e01e5f38c3c10570ae6e96b9e382b2e02084 100644 (file)
@@ -78,6 +78,7 @@ int  ksocket_sendto(int sid, const void* buf, size_t len, int flags,
 int  ksocket_recvfrom(int sid, void* buf, size_t len, int flags,
                       struct sockaddr_in* src);
 int  ksocket_close(int sid);
+int  ksocket_poll(int sid, int events);
 void ksocket_init(void);
 
 #endif
index 2fd3a56037181ffeeea306f662a4b1f29dae318b..7b63e3934f03b5f78f4829670db45bd4f15ce180 100644 (file)
@@ -1,4 +1,5 @@
 #include "socket.h"
+#include "fs.h"
 #include "net.h"
 #include "errno.h"
 #include "process.h"
@@ -433,3 +434,34 @@ int ksocket_close(int sid) {
     s->in_use = 0;
     return 0;
 }
+
+int ksocket_poll(int sid, int events) {
+    if (sid < 0 || sid >= KSOCKET_MAX) return VFS_POLL_ERR;
+    struct ksocket* s = &sockets[sid];
+    if (!s->in_use) return VFS_POLL_ERR | VFS_POLL_HUP;
+
+    int revents = 0;
+
+    if (s->error) revents |= VFS_POLL_ERR;
+
+    if (s->state == KSOCK_PEER_CLOSED || s->state == KSOCK_CLOSED) {
+        revents |= VFS_POLL_HUP;
+        /* Peer-closed socket is still readable (returns EOF / remaining data) */
+        if (events & VFS_POLL_IN) revents |= VFS_POLL_IN;
+        return revents;
+    }
+
+    if (events & VFS_POLL_IN) {
+        if (s->state == KSOCK_LISTENING) {
+            if (s->aq_count > 0) revents |= VFS_POLL_IN;
+        } else {
+            if (s->rx_count > 0) revents |= VFS_POLL_IN;
+        }
+    }
+
+    if (events & VFS_POLL_OUT) {
+        if (s->state == KSOCK_CONNECTED) revents |= VFS_POLL_OUT;
+    }
+
+    return revents;
+}
index c7c4a32cc18afb5fe081af8d1433d41ee030946c..93c61734c083c48a9cce56a089d1f781ca271249 100644 (file)
@@ -2745,10 +2745,16 @@ static void sock_node_close(fs_node_t* node) {
     kfree(node);
 }
 
+static int sock_node_poll(fs_node_t* node, int events) {
+    if (!node) return VFS_POLL_ERR;
+    return ksocket_poll((int)node->inode, events);
+}
+
 static const struct file_operations sock_fops = {
     .read  = sock_node_read,
     .write = sock_node_write,
     .close = sock_node_close,
+    .poll  = sock_node_poll,
 };
 
 static fs_node_t* sock_node_create(int sid) {