2023-04-10 17:56:03 +00:00
|
|
|
#include "memory/MemoryManager.h"
|
|
|
|
#include "sys/Syscall.h"
|
|
|
|
#include "thread/Scheduler.h"
|
|
|
|
#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;
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Result<u64> do_stat(SharedPtr<VFS::Inode> inode, stat* st)
|
|
|
|
{
|
|
|
|
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();
|
|
|
|
|
|
|
|
if (!MemoryManager::copy_to_user_typed(st, &kstat)) return err(EFAULT);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<u64> sys_stat(Registers*, SyscallArgs args)
|
|
|
|
{
|
|
|
|
auto path = TRY(MemoryManager::strdup_from_user(args[0]));
|
|
|
|
stat* st = (stat*)args[1];
|
|
|
|
|
|
|
|
Thread* current = Scheduler::current();
|
|
|
|
|
2023-04-11 20:14:57 +00:00
|
|
|
auto inode = TRY(VFS::resolve_path(path.chars(), current->auth, current->current_directory));
|
2023-04-10 17:56:03 +00:00
|
|
|
|
|
|
|
return do_stat(inode, st);
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<u64> sys_fstat(Registers*, SyscallArgs args)
|
|
|
|
{
|
|
|
|
int fd = (int)args[0];
|
|
|
|
stat* st = (stat*)args[1];
|
|
|
|
|
|
|
|
Thread* current = Scheduler::current();
|
|
|
|
|
|
|
|
auto descriptor = *TRY(current->resolve_fd(fd));
|
|
|
|
|
|
|
|
return do_stat(descriptor.inode, st);
|
|
|
|
}
|