#include "fs/VFS.h" #include "interrupts/Context.h" #include "std/errno.h" #include "std/stdlib.h" #include "sys/UserMemory.h" #include "thread/Scheduler.h" typedef unsigned short mode_t; typedef unsigned long ino_t; struct stat // FIXME: This struct is quite stubbed out. { ino_t st_ino; mode_t st_mode; off_t st_size; int st_dev; // FIXME: Implement this. int st_nlink; // FIXME: Implement this. uid_t st_uid; gid_t st_gid; time_t st_atime; time_t st_mtime; time_t st_ctime; }; void do_stat(Context* context, VFS::Node* node, struct stat* buf) { struct stat stat; stat.st_ino = node->inode; stat.st_mode = node->mode | ((1 << (node->type)) * 010000); stat.st_size = node->length; stat.st_uid = node->uid; stat.st_gid = node->gid; stat.st_atime = node->atime; stat.st_ctime = node->ctime; stat.st_mtime = node->mtime; stat.st_dev = 0; stat.st_nlink = 0; if (!copy_typed_to_user(buf, &stat)) context->rax = -EFAULT; else context->rax = 0; } void sys_fstat(Context* context, int fd, struct stat* buf) { Task* current_task = Scheduler::current_task(); if (fd < 0 || fd >= TASK_MAX_FDS) { context->rax = -EBADF; return; } Descriptor& file = current_task->files[fd]; if (!file.is_open()) { context->rax = -EBADF; return; } VFS::Node* node = file.node(); return do_stat(context, node, buf); } void sys_stat(Context* context, const char* path, struct stat* buf) { auto result = strdup_from_user(path); if (result.has_error()) { context->rax = -result.error(); return; } char* kpath = result.release_value(); VFS::Node* node = VFS::resolve_path(kpath); kfree(kpath); if (!node) { context->rax = -ENOENT; return; } return do_stat(context, node, buf); }