diff --git a/kernel/include/scheduler.hpp b/kernel/include/scheduler.hpp index 74206caf..2e17f0cd 100644 --- a/kernel/include/scheduler.hpp +++ b/kernel/include/scheduler.hpp @@ -38,6 +38,7 @@ void sleep_ms(pid_t pid, size_t time); size_t register_new_handle(const std::string& path); bool has_handle(size_t fd); +void release_handle(size_t fd); const std::string& get_handle(size_t fd); } //end of namespace scheduler diff --git a/kernel/include/vfs.hpp b/kernel/include/vfs.hpp index 10d53b59..2871f1aa 100644 --- a/kernel/include/vfs.hpp +++ b/kernel/include/vfs.hpp @@ -15,6 +15,7 @@ namespace vfs { int64_t open(const char* file); +void close(size_t fd); int64_t stat(size_t fd, stat_info& info); } //end of namespace vfs diff --git a/kernel/src/scheduler.cpp b/kernel/src/scheduler.cpp index b63f6670..1f4f0523 100644 --- a/kernel/src/scheduler.cpp +++ b/kernel/src/scheduler.cpp @@ -814,6 +814,10 @@ size_t scheduler::register_new_handle(const std::string& path){ return pcb[current_pid].handles.size() - 1; } +void scheduler::release_handle(size_t fd){ + pcb[current_pid].handles[fd] = nullptr; +} + bool scheduler::has_handle(size_t fd){ return pcb[current_pid].handles.size() - 1 <= fd; } diff --git a/kernel/src/system_calls.cpp b/kernel/src/system_calls.cpp index fe589105..984751b0 100644 --- a/kernel/src/system_calls.cpp +++ b/kernel/src/system_calls.cpp @@ -109,6 +109,12 @@ void sc_open(interrupt::syscall_regs* regs){ regs->rax = vfs::open(file); } +void sc_close(interrupt::syscall_regs* regs){ + auto fd = regs->rbx; + + vfs::close(fd); +} + void sc_stat(interrupt::syscall_regs* regs){ auto fd = regs->rbx; auto info = reinterpret_cast(regs->rcx); @@ -186,6 +192,10 @@ void system_call_entry(interrupt::syscall_regs* regs){ sc_stat(regs); break; + case 302: + sc_close(regs); + break; + case 0x666: //TODO Do something with return code scheduler::kill_current_process(); diff --git a/kernel/src/vfs.cpp b/kernel/src/vfs.cpp index ae29b0f5..1339b16c 100644 --- a/kernel/src/vfs.cpp +++ b/kernel/src/vfs.cpp @@ -55,6 +55,12 @@ int64_t vfs::open(const char* file_path){ return -std::ERROR_NOT_EXISTS; } +void vfs::close(size_t fd){ + if(scheduler::has_handle(fd)){ + scheduler::release_handle(fd); + } +} + int64_t vfs::stat(size_t fd, stat_info& info){ if(!disks::mounted_partition() || !disks::mounted_disk()){ return -std::ERROR_NOTHING_MOUNTED; diff --git a/programs/stat/src/main.cpp b/programs/stat/src/main.cpp index ebc67c6a..525e9f93 100644 --- a/programs/stat/src/main.cpp +++ b/programs/stat/src/main.cpp @@ -87,6 +87,8 @@ int main(int argc, char* argv[]){ } else { printf("stat: error: %s\n", std::error_message(info.error())); } + + close(*fd); } else { printf("stat: error: %s\n", std::error_message(fd.error())); } diff --git a/tlib/include/file.hpp b/tlib/include/file.hpp index 21cc23ab..41fc3c18 100644 --- a/tlib/include/file.hpp +++ b/tlib/include/file.hpp @@ -14,6 +14,7 @@ #include std::expected open(const char* file); +void close(size_t fd); std::expected stat(size_t fd); #endif diff --git a/tlib/src/file.cpp b/tlib/src/file.cpp index d806f508..2dc8fd9b 100644 --- a/tlib/src/file.cpp +++ b/tlib/src/file.cpp @@ -20,6 +20,12 @@ std::expected open(const char* file){ return std::make_expected(fd); } } +void close(size_t fd){ + asm volatile("mov rax, 302; mov rbx, %[fd]; int 50;" + : /* No outputs */ + : [fd] "g" (fd) + : "rax", "rbx"); +} std::expected stat(size_t fd){ stat_info info;