Luna/kernel/src/sys/getdents.cpp

40 lines
1005 B
C++

#include "fs/VFS.h"
#include "memory/MemoryManager.h"
#include "sys/Syscall.h"
#include "thread/Scheduler.h"
#include <bits/getdents.h>
Result<u64> sys_getdents(Registers*, SyscallArgs args)
{
int fd = (int)args[0];
luna_dirent* ent = (luna_dirent*)args[1];
usize count = (usize)args[2];
Thread* current = Scheduler::current();
auto& descriptor = *TRY(current->resolve_fd(fd));
if (descriptor.inode->type() != VFS::InodeType::Directory) return err(ENOTDIR);
usize nwrite = 0;
while (nwrite < count)
{
VFS::DirectoryEntry entry;
bool ok = descriptor.inode->get(descriptor.offset).try_set_value(entry);
if (!ok) break;
descriptor.offset++;
luna_dirent kent;
kent.inode = entry.inode->inode_number();
strlcpy(kent.name, entry.name.chars(), entry.name.length() + 1);
if (!MemoryManager::copy_to_user_typed(ent, &kent)) return err(EFAULT);
ent++;
nwrite++;
}
return nwrite;
}