#define MODULE "dir" #include "luna/dirent.h" #include "fs/VFS.h" #include "interrupts/Context.h" #include "std/errno.h" #include "std/string.h" #include "sys/UserMemory.h" #include "thread/Scheduler.h" void sys_getdents(Context* context, int fd, struct luna_dirent* buf, size_t count) { if (fd < 0 || fd > TASK_MAX_FDS) { context->rax = -EBADF; return; } Task* current_task = Scheduler::current_task(); if (!current_task->files[fd].is_open()) { context->rax = -EBADF; return; } Descriptor& dir = current_task->files[fd]; VFS::Node* node = dir.node(); if (node->type != VFS_DIRECTORY) { context->rax = -ENOTDIR; return; } size_t nread = 0; while (count) { VFS::Node* entry = VFS::readdir(node, dir.offset()); if (!entry) { context->rax = nread; return; } auto* kdirent = obtain_user_ref(buf); if (!kdirent) { context->rax = -EFAULT; return; } kdirent->total = node->length; kdirent->offset = dir.offset(); kdirent->inode = entry->inode; strlcpy(kdirent->name, entry->name, sizeof(kdirent->name)); release_user_ref(kdirent); dir.seek(dir.offset() + 1); buf++; nread++; count--; } context->rax = nread; }