#include "memory/MemoryManager.h" #include "sys/Syscall.h" #include "thread/Scheduler.h" #include #include 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 do_stat(SharedPtr 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 sys_stat(Registers*, SyscallArgs args) { auto path = TRY(MemoryManager::strdup_from_user(args[0])); stat* st = (stat*)args[1]; Thread* current = Scheduler::current(); auto inode = TRY(VFS::resolve_path(path.chars(), current->auth, current->current_directory)); return do_stat(inode, st); } Result 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); }