From: Tulio A M Mendes Date: Fri, 13 Feb 2026 23:52:38 +0000 (-0300) Subject: feat: socket poll support — wire ksocket_poll into sock_fops X-Git-Url: https://projects.tadryanom.me/docs/static/git-favicon.png?a=commitdiff_plain;h=7821d4365f4009534fb21229c4116efd147e3c5c;p=AdrOS.git feat: socket poll support — wire ksocket_poll into sock_fops 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. --- diff --git a/include/socket.h b/include/socket.h index 327f910..ab06e01 100644 --- a/include/socket.h +++ b/include/socket.h @@ -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 diff --git a/src/kernel/socket.c b/src/kernel/socket.c index 2fd3a56..7b63e39 100644 --- a/src/kernel/socket.c +++ b/src/kernel/socket.c @@ -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; +} diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index c7c4a32..93c6173 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -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) {