#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); if (fd < 0 || fd >= FD_MAX) return err(EBADF); Thread* current = Scheduler::current(); Option& descriptor = current->fd_table->fds[fd]; if (!descriptor.has_value()) return err(EBADF); 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); if (fd < 0 || fd >= FD_MAX) return err(EBADF); Thread* current = Scheduler::current(); Option& descriptor = current->fd_table->fds[fd]; if (!descriptor.has_value()) return err(EBADF); 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]; if (fd < 0 || fd >= FD_MAX) return err(EBADF); Thread* current = Scheduler::current(); Option& descriptor = current->fd_table->fds[fd]; if (!descriptor.has_value()) return err(EBADF); 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: todo(); default: return err(EINVAL); } if (new_offset < 0) return err(EINVAL); descriptor->offset = (usize)new_offset; return (u64)new_offset; }