]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
refactor: replace socket magic 0x534F434B with proper VFS FS_SOCKET nodes
authorTulio A M Mendes <[email protected]>
Fri, 13 Feb 2026 18:45:18 +0000 (15:45 -0300)
committerTulio A M Mendes <[email protected]>
Fri, 13 Feb 2026 18:45:18 +0000 (15:45 -0300)
- Add FS_SOCKET type to fs.h
- Create sock_node_create/close/read/write: proper fs_node_t for sockets
  with read→ksocket_recv, write→ksocket_send, close→ksocket_close
- Socket ID stored in node->inode (previously in file->offset)
- sock_fd_get_sid helper validates socket FDs via FS_SOCKET type check
- socket()/accept() now create VFS nodes instead of magic-flagged files
- fd_close no longer needs special socket magic check
- read()/write() on socket FDs now work via standard VFS dispatch
- All 0x534F434BU magic references eliminated from codebase

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

index 91d93ae3cd554e3c874d87f8a314330acc2ddf29..ed5b61c5249e783057fe8743ba5339e32dd6af71 100644 (file)
@@ -9,6 +9,7 @@
 #define FS_CHARDEVICE  0x03
 #define FS_BLOCKDEVICE 0x04
 #define FS_SYMLINK     0x05
+#define FS_SOCKET      0x06
 
 /* poll() event flags — shared between kernel VFS and syscall layer */
 #define VFS_POLL_IN    0x0001
index b590d5a80e6440ff18ddc8eb617247f7f45bbe72..8c92023bc9bf945f64797032785a4f454689b0ad 100644 (file)
@@ -596,9 +596,7 @@ static int fd_close(int fd) {
     current_process->files[fd] = NULL;
 
     if (__sync_sub_and_fetch(&f->refcount, 1) == 0) {
-        if (f->flags == 0x534F434BU && f->node == NULL) {
-            ksocket_close((int)f->offset);
-        } else if (f->node) {
+        if (f->node) {
             vfs_close(f->node);
         }
         kfree(f);
@@ -1283,7 +1281,7 @@ static int syscall_write_impl(int fd, const void* user_buf, uint32_t len) {
             return -EAGAIN;
     }
     if (!f->node->write) return -ESPIPE;
-    if (((f->node->flags & FS_FILE) == 0) && f->node->flags != FS_CHARDEVICE) return -ESPIPE;
+    if (f->node->flags != FS_FILE && f->node->flags != FS_CHARDEVICE && f->node->flags != FS_SOCKET) return -ESPIPE;
 
     if ((f->flags & O_APPEND) && (f->node->flags & FS_FILE)) {
         f->offset = f->node->length;
@@ -2586,6 +2584,50 @@ static void posix_ext_syscall_dispatch(struct registers* regs, uint32_t syscall_
     sc_ret(regs) = (uint32_t)-ENOSYS;
 }
 
+/* --- Socket VFS node --- */
+
+static uint32_t sock_node_read(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer) {
+    (void)offset;
+    if (!node || !buffer) return 0;
+    int sid = (int)node->inode;
+    int rc = ksocket_recv(sid, buffer, size, 0);
+    return (rc > 0) ? (uint32_t)rc : 0;
+}
+
+static uint32_t sock_node_write(fs_node_t* node, uint32_t offset, uint32_t size, const uint8_t* buffer) {
+    (void)offset;
+    if (!node || !buffer) return 0;
+    int sid = (int)node->inode;
+    int rc = ksocket_send(sid, buffer, size, 0);
+    return (rc > 0) ? (uint32_t)rc : 0;
+}
+
+static void sock_node_close(fs_node_t* node) {
+    if (!node) return;
+    ksocket_close((int)node->inode);
+    kfree(node);
+}
+
+static fs_node_t* sock_node_create(int sid) {
+    fs_node_t* n = (fs_node_t*)kmalloc(sizeof(fs_node_t));
+    if (!n) return NULL;
+    memset(n, 0, sizeof(*n));
+    strcpy(n->name, "socket");
+    n->flags = FS_SOCKET;
+    n->inode = (uint32_t)sid;
+    n->read = sock_node_read;
+    n->write = sock_node_write;
+    n->close = sock_node_close;
+    return n;
+}
+
+static inline int sock_fd_get_sid(int fd) {
+    if (fd < 0 || fd >= PROCESS_MAX_FILES) return -EBADF;
+    struct file* f = current_process->files[fd];
+    if (!f || !f->node || f->node->flags != FS_SOCKET) return -EBADF;
+    return (int)f->node->inode;
+}
+
 /* Separate function to keep socket locals off syscall_handler's stack frame */
 __attribute__((noinline))
 static void socket_syscall_dispatch(struct registers* regs, uint32_t syscall_no) {
@@ -2595,71 +2637,55 @@ static void socket_syscall_dispatch(struct registers* regs, uint32_t syscall_no)
         int protocol = (int)sc_arg2(regs);
         int sid = ksocket_create(domain, type, protocol);
         if (sid < 0) { sc_ret(regs) = (uint32_t)sid; return; }
-        int fd = -1;
-        for (int i = 0; i < PROCESS_MAX_FILES; i++) {
-            if (!current_process->files[i]) { fd = i; break; }
-        }
-        if (fd < 0) { ksocket_close(sid); sc_ret(regs) = (uint32_t)-EMFILE; return; }
+        fs_node_t* sn = sock_node_create(sid);
+        if (!sn) { ksocket_close(sid); sc_ret(regs) = (uint32_t)-ENOMEM; return; }
         struct file* f = (struct file*)kmalloc(sizeof(struct file));
-        if (!f) { ksocket_close(sid); sc_ret(regs) = (uint32_t)-ENOMEM; return; }
-        f->node = NULL;
-        f->offset = (uint32_t)sid;
-        f->flags = 0x534F434BU;     /* magic 'SOCK' */
+        if (!f) { sock_node_close(sn); sc_ret(regs) = (uint32_t)-ENOMEM; return; }
+        f->node = sn;
+        f->offset = 0;
+        f->flags = 0;
         f->refcount = 1;
-        current_process->files[fd] = f;
+        int fd = fd_alloc(f);
+        if (fd < 0) { sock_node_close(sn); kfree(f); sc_ret(regs) = (uint32_t)-EMFILE; return; }
         sc_ret(regs) = (uint32_t)fd;
         return;
     }
 
     if (syscall_no == SYSCALL_BIND) {
-        int fd = (int)sc_arg0(regs);
-        if (fd < 0 || fd >= PROCESS_MAX_FILES || !current_process->files[fd] ||
-            current_process->files[fd]->flags != 0x534F434BU) {
-            sc_ret(regs) = (uint32_t)-EBADF; return;
-        }
+        int sid = sock_fd_get_sid((int)sc_arg0(regs));
+        if (sid < 0) { sc_ret(regs) = (uint32_t)-EBADF; return; }
         struct sockaddr_in sa;
         if (copy_from_user(&sa, (const void*)sc_arg1(regs), sizeof(sa)) < 0) {
             sc_ret(regs) = (uint32_t)-EFAULT; return;
         }
-        int sid = (int)current_process->files[fd]->offset;
         sc_ret(regs) = (uint32_t)ksocket_bind(sid, &sa);
         return;
     }
 
     if (syscall_no == SYSCALL_LISTEN) {
-        int fd = (int)sc_arg0(regs);
-        if (fd < 0 || fd >= PROCESS_MAX_FILES || !current_process->files[fd] ||
-            current_process->files[fd]->flags != 0x534F434BU) {
-            sc_ret(regs) = (uint32_t)-EBADF; return;
-        }
-        int sid = (int)current_process->files[fd]->offset;
+        int sid = sock_fd_get_sid((int)sc_arg0(regs));
+        if (sid < 0) { sc_ret(regs) = (uint32_t)-EBADF; return; }
         sc_ret(regs) = (uint32_t)ksocket_listen(sid, (int)sc_arg1(regs));
         return;
     }
 
     if (syscall_no == SYSCALL_ACCEPT) {
-        int fd = (int)sc_arg0(regs);
-        if (fd < 0 || fd >= PROCESS_MAX_FILES || !current_process->files[fd] ||
-            current_process->files[fd]->flags != 0x534F434BU) {
-            sc_ret(regs) = (uint32_t)-EBADF; return;
-        }
-        int sid = (int)current_process->files[fd]->offset;
+        int sid = sock_fd_get_sid((int)sc_arg0(regs));
+        if (sid < 0) { sc_ret(regs) = (uint32_t)-EBADF; return; }
         struct sockaddr_in sa;
         memset(&sa, 0, sizeof(sa));
         int new_sid = ksocket_accept(sid, &sa);
         if (new_sid < 0) { sc_ret(regs) = (uint32_t)new_sid; return; }
-        int new_fd = -1;
-        for (int i = 0; i < PROCESS_MAX_FILES; i++) {
-            if (!current_process->files[i]) { new_fd = i; break; }
-        }
-        if (new_fd < 0) { ksocket_close(new_sid); sc_ret(regs) = (uint32_t)-EMFILE; return; }
+        fs_node_t* sn = sock_node_create(new_sid);
+        if (!sn) { ksocket_close(new_sid); sc_ret(regs) = (uint32_t)-ENOMEM; return; }
         struct file* f = (struct file*)kmalloc(sizeof(struct file));
-        if (!f) { ksocket_close(new_sid); sc_ret(regs) = (uint32_t)-ENOMEM; return; }
-        f->node = NULL;
-        f->offset = (uint32_t)new_sid;
-        f->flags = 0x534F434BU;
+        if (!f) { sock_node_close(sn); sc_ret(regs) = (uint32_t)-ENOMEM; return; }
+        f->node = sn;
+        f->offset = 0;
+        f->flags = 0;
         f->refcount = 1;
-        current_process->files[new_fd] = f;
+        int new_fd = fd_alloc(f);
+        if (new_fd < 0) { sock_node_close(sn); kfree(f); sc_ret(regs) = (uint32_t)-EMFILE; return; }
         if (sc_arg1(regs)) {
             (void)copy_to_user((void*)sc_arg1(regs), &sa, sizeof(sa));
         }
@@ -2668,56 +2694,41 @@ static void socket_syscall_dispatch(struct registers* regs, uint32_t syscall_no)
     }
 
     if (syscall_no == SYSCALL_CONNECT) {
-        int fd = (int)sc_arg0(regs);
-        if (fd < 0 || fd >= PROCESS_MAX_FILES || !current_process->files[fd] ||
-            current_process->files[fd]->flags != 0x534F434BU) {
-            sc_ret(regs) = (uint32_t)-EBADF; return;
-        }
+        int sid = sock_fd_get_sid((int)sc_arg0(regs));
+        if (sid < 0) { sc_ret(regs) = (uint32_t)-EBADF; return; }
         struct sockaddr_in sa;
         if (copy_from_user(&sa, (const void*)sc_arg1(regs), sizeof(sa)) < 0) {
             sc_ret(regs) = (uint32_t)-EFAULT; return;
         }
-        int sid = (int)current_process->files[fd]->offset;
         sc_ret(regs) = (uint32_t)ksocket_connect(sid, &sa);
         return;
     }
 
     if (syscall_no == SYSCALL_SEND) {
-        int fd = (int)sc_arg0(regs);
-        if (fd < 0 || fd >= PROCESS_MAX_FILES || !current_process->files[fd] ||
-            current_process->files[fd]->flags != 0x534F434BU) {
-            sc_ret(regs) = (uint32_t)-EBADF; return;
-        }
+        int sid = sock_fd_get_sid((int)sc_arg0(regs));
+        if (sid < 0) { sc_ret(regs) = (uint32_t)-EBADF; return; }
         size_t len = (size_t)sc_arg2(regs);
         if (!user_range_ok((const void*)sc_arg1(regs), len)) {
             sc_ret(regs) = (uint32_t)-EFAULT; return;
         }
-        int sid = (int)current_process->files[fd]->offset;
         sc_ret(regs) = (uint32_t)ksocket_send(sid, (const void*)sc_arg1(regs), len, (int)sc_arg3(regs));
         return;
     }
 
     if (syscall_no == SYSCALL_RECV) {
-        int fd = (int)sc_arg0(regs);
-        if (fd < 0 || fd >= PROCESS_MAX_FILES || !current_process->files[fd] ||
-            current_process->files[fd]->flags != 0x534F434BU) {
-            sc_ret(regs) = (uint32_t)-EBADF; return;
-        }
+        int sid = sock_fd_get_sid((int)sc_arg0(regs));
+        if (sid < 0) { sc_ret(regs) = (uint32_t)-EBADF; return; }
         size_t len = (size_t)sc_arg2(regs);
         if (!user_range_ok((void*)sc_arg1(regs), len)) {
             sc_ret(regs) = (uint32_t)-EFAULT; return;
         }
-        int sid = (int)current_process->files[fd]->offset;
         sc_ret(regs) = (uint32_t)ksocket_recv(sid, (void*)sc_arg1(regs), len, (int)sc_arg3(regs));
         return;
     }
 
     if (syscall_no == SYSCALL_SENDTO) {
-        int fd = (int)sc_arg0(regs);
-        if (fd < 0 || fd >= PROCESS_MAX_FILES || !current_process->files[fd] ||
-            current_process->files[fd]->flags != 0x534F434BU) {
-            sc_ret(regs) = (uint32_t)-EBADF; return;
-        }
+        int sid = sock_fd_get_sid((int)sc_arg0(regs));
+        if (sid < 0) { sc_ret(regs) = (uint32_t)-EBADF; return; }
         size_t len = (size_t)sc_arg2(regs);
         if (!user_range_ok((const void*)sc_arg1(regs), len)) {
             sc_ret(regs) = (uint32_t)-EFAULT; return;
@@ -2726,25 +2737,20 @@ static void socket_syscall_dispatch(struct registers* regs, uint32_t syscall_no)
         if (copy_from_user(&dest, (const void*)sc_arg4(regs), sizeof(dest)) < 0) {
             sc_ret(regs) = (uint32_t)-EFAULT; return;
         }
-        int sid = (int)current_process->files[fd]->offset;
         sc_ret(regs) = (uint32_t)ksocket_sendto(sid, (const void*)sc_arg1(regs), len,
                                               (int)sc_arg3(regs), &dest);
         return;
     }
 
     if (syscall_no == SYSCALL_RECVFROM) {
-        int fd = (int)sc_arg0(regs);
-        if (fd < 0 || fd >= PROCESS_MAX_FILES || !current_process->files[fd] ||
-            current_process->files[fd]->flags != 0x534F434BU) {
-            sc_ret(regs) = (uint32_t)-EBADF; return;
-        }
+        int sid = sock_fd_get_sid((int)sc_arg0(regs));
+        if (sid < 0) { sc_ret(regs) = (uint32_t)-EBADF; return; }
         size_t len = (size_t)sc_arg2(regs);
         if (!user_range_ok((void*)sc_arg1(regs), len)) {
             sc_ret(regs) = (uint32_t)-EFAULT; return;
         }
         struct sockaddr_in src;
         memset(&src, 0, sizeof(src));
-        int sid = (int)current_process->files[fd]->offset;
         int ret = ksocket_recvfrom(sid, (void*)sc_arg1(regs), len, (int)sc_arg3(regs), &src);
         if (ret > 0 && sc_arg4(regs)) {
             (void)copy_to_user((void*)sc_arg4(regs), &src, sizeof(src));