diff --git a/kernel/include/vfs/vfs.hpp b/kernel/include/vfs/vfs.hpp index 271fba81..8e7689b2 100644 --- a/kernel/include/vfs/vfs.hpp +++ b/kernel/include/vfs/vfs.hpp @@ -29,6 +29,8 @@ int64_t statfs(const char* mount_point, statfs_info& info); int64_t mkdir(const char* file); int64_t rm(const char* file); int64_t read(size_t fd, char* buffer, size_t count, size_t offset = 0); +int64_t write(size_t fd, char* buffer, size_t count, size_t offset = 0); +int64_t truncate(size_t fd, size_t size); int64_t entries(size_t fd, char* buffer, size_t size); int64_t mounts(char* buffer, size_t size); diff --git a/kernel/src/system_calls.cpp b/kernel/src/system_calls.cpp index 4b835f19..6564c289 100644 --- a/kernel/src/system_calls.cpp +++ b/kernel/src/system_calls.cpp @@ -140,6 +140,22 @@ void sc_read(interrupt::syscall_regs* regs){ regs->rax = vfs::read(fd, buffer, max, offset); } +void sc_write(interrupt::syscall_regs* regs){ + auto fd = regs->rbx; + auto buffer = reinterpret_cast(regs->rcx); + auto max = regs->rdx; + auto offset = regs->rsi; + + regs->rax = vfs::write(fd, buffer, max, offset); +} + +void sc_truncate(interrupt::syscall_regs* regs){ + auto fd = regs->rbx; + auto size = regs->rcx; + + regs->rax = vfs::truncate(fd, size); +} + void sc_entries(interrupt::syscall_regs* regs){ auto fd = regs->rbx; auto buffer = reinterpret_cast(regs->rcx); @@ -305,6 +321,14 @@ void system_call_entry(interrupt::syscall_regs* regs){ sc_statfs(regs); break; + case 311: + sc_write(regs); + break; + + case 312: + sc_truncate(regs); + break; + case 400: sc_datetime(regs); break; diff --git a/kernel/src/vfs/vfs.cpp b/kernel/src/vfs/vfs.cpp index 80b54115..91b27b87 100644 --- a/kernel/src/vfs/vfs.cpp +++ b/kernel/src/vfs/vfs.cpp @@ -304,6 +304,48 @@ int64_t vfs::read(size_t fd, char* buffer, size_t count, size_t offset){ return read; } +int64_t vfs::write(size_t fd, char* buffer, size_t count, size_t offset){ + if(!scheduler::has_handle(fd)){ + return -std::ERROR_INVALID_FILE_DESCRIPTOR; + } + + auto path = scheduler::get_handle(fd); + + if(path.empty()){ + return -std::ERROR_INVALID_FILE_PATH; + } + + auto& fs = get_fs(path); + auto fs_path = get_fs_path(path, fs); + + size_t written = 0; + auto result = fs.file_system->write(fs_path, buffer, count, offset, written); + + if(result > 0){ + return -result; + } + + return written; +} + +int64_t vfs::truncate(size_t fd, size_t size){ + if(!scheduler::has_handle(fd)){ + return -std::ERROR_INVALID_FILE_DESCRIPTOR; + } + + auto path = scheduler::get_handle(fd); + + if(path.empty()){ + return -std::ERROR_INVALID_FILE_PATH; + } + + auto& fs = get_fs(path); + auto fs_path = get_fs_path(path, fs); + + auto result = fs.file_system->truncate(fs_path, size); + return result > 0 ? -result : 0; +} + int64_t vfs::direct_read(const std::string& file_path, std::string& content){ auto path = get_path(file_path.c_str()); auto& fs = get_fs(path);