Luna/kernel/src/sys/stat.cpp

50 lines
1.4 KiB
C++
Raw Normal View History

2023-04-10 17:56:03 +00:00
#include "memory/MemoryManager.h"
#include "sys/Syscall.h"
#include "thread/Scheduler.h"
#include <bits/atfile.h>
2023-04-10 17:56:03 +00:00
#include <bits/modes.h>
#include <bits/struct_stat.h>
static mode_t make_mode(mode_t mode, VFS::InodeType type)
{
mode_t result = mode;
switch (type)
{
case VFS::InodeType::RegularFile: result |= S_IFREG; break;
case VFS::InodeType::Directory: result |= S_IFDIR; break;
case VFS::InodeType::Device: result |= S_IFCHR; break;
case VFS::InodeType::Symlink: result |= S_IFLNK; break;
2023-04-10 17:56:03 +00:00
default: break;
}
return result;
}
Result<u64> sys_fstatat(Registers*, SyscallArgs args)
2023-04-10 17:56:03 +00:00
{
int dirfd = (int)args[0];
auto path = TRY(MemoryManager::strdup_from_user(args[1]));
stat* st = (stat*)args[2];
int flags = (int)args[3];
Thread* current = Scheduler::current();
auto inode = TRY(current->resolve_atfile(dirfd, path, flags & AT_EMPTY_PATH, !(flags & AT_SYMLINK_NOFOLLOW)));
2023-04-10 17:56:03 +00:00
stat kstat;
kstat.st_ino = inode->inode_number();
kstat.st_mode = make_mode(inode->mode(), inode->type());
kstat.st_nlink = 1; // FIXME: Count hard links to files.
kstat.st_uid = inode->uid();
kstat.st_gid = inode->gid();
kstat.st_size = inode->size();
2023-05-23 18:49:26 +00:00
kstat.st_dev = inode->fs() ? inode->fs()->host_device_id() : 0;
2023-05-23 18:45:24 +00:00
kstat.st_rdev = inode->device_id();
2023-04-10 17:56:03 +00:00
if (!MemoryManager::copy_to_user_typed(st, &kstat)) return err(EFAULT);
return 0;
}