#include "Log.h" #include "fs/VFS.h" #include "memory/MemoryManager.h" #include "sys/Syscall.h" #include "thread/Scheduler.h" #include #include #include Result sys_read(Registers*, SyscallArgs args) { int fd = (int)args[0]; u8* buf = (u8*)args[1]; usize size = (usize)args[2]; if (!MemoryManager::validate_user_write(buf, size)) return err(EFAULT); Thread* current = Scheduler::current(); auto& descriptor = *TRY(current->resolve_fd(fd)); if (!descriptor.is_readable()) return err(EBADF); while (descriptor.inode->blocking()) { kernel_sleep(10); } usize nread = TRY(descriptor.inode->read(buf, descriptor.offset, size)); descriptor.offset += nread; return nread; } Result sys_write(Registers*, SyscallArgs args) { int fd = (int)args[0]; const u8* buf = (const u8*)args[1]; usize size = (usize)args[2]; if (!MemoryManager::validate_user_read(buf, size)) return err(EFAULT); Thread* current = Scheduler::current(); auto& descriptor = *TRY(current->resolve_fd(fd)); if (!descriptor.is_writable()) return err(EBADF); if (descriptor.should_append()) descriptor.offset = descriptor.inode->size(); usize nwritten = TRY(descriptor.inode->write(buf, descriptor.offset, size)); descriptor.offset += nwritten; return nwritten; } Result sys_lseek(Registers*, SyscallArgs args) { int fd = (int)args[0]; off_t offset = (long)args[1]; int whence = (int)args[2]; Thread* current = Scheduler::current(); auto& descriptor = *TRY(current->resolve_fd(fd)); off_t new_offset; switch (whence) { case SEEK_SET: new_offset = offset; break; case SEEK_CUR: new_offset = TRY(safe_add((long)descriptor.offset, offset)); break; case SEEK_END: new_offset = TRY(safe_add((long)descriptor.inode->size(), offset)); break; default: return err(EINVAL); } if (new_offset < 0) return err(EINVAL); descriptor.offset = (usize)new_offset; return (u64)new_offset; }