diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 54884377..95139aee 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -98,6 +98,7 @@ namespace Kernel BAN::ErrorOr sys_write(int fd, const void* buffer, size_t count); BAN::ErrorOr sys_create(const char*, mode_t); BAN::ErrorOr sys_create_dir(const char*, mode_t); + BAN::ErrorOr sys_unlink(const char*); BAN::ErrorOr sys_chmod(const char*, mode_t); diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index b6edb963..e8bee629 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -634,7 +634,7 @@ namespace Kernel auto directory = absolute_path.sv().substring(0, index); auto file_name = absolute_path.sv().substring(index); - auto parent_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, directory, O_WRONLY)).inode; + auto parent_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, directory, O_EXEC | O_WRONLY)).inode; if (Inode::Mode(mode).ifdir()) TRY(parent_inode->create_directory(file_name, mode, m_credentials.euid(), m_credentials.egid())); @@ -762,6 +762,26 @@ namespace Kernel return 0; } + BAN::ErrorOr Process::sys_unlink(const char* path) + { + LockGuard _(m_lock); + validate_string_access(path); + + auto absolute_path = TRY(absolute_path_of(path)); + + size_t index = absolute_path.size(); + for (; index > 0; index--) + if (absolute_path[index - 1] == '/') + break; + auto directory = absolute_path.sv().substring(0, index); + auto file_name = absolute_path.sv().substring(index); + + auto parent = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, directory, O_EXEC | O_WRONLY)).inode; + TRY(parent->unlink(file_name)); + + return 0; + } + BAN::ErrorOr Process::sys_chmod(const char* path, mode_t mode) { if (mode & S_IFMASK) diff --git a/kernel/kernel/Syscall.cpp b/kernel/kernel/Syscall.cpp index 6b0a4249..ab7c3ce8 100644 --- a/kernel/kernel/Syscall.cpp +++ b/kernel/kernel/Syscall.cpp @@ -208,6 +208,9 @@ namespace Kernel case SYS_CREATE_DIR: ret = Process::current().sys_create_dir((const char*)arg1, (mode_t)arg2); break; + case SYS_UNLINK: + ret = Process::current().sys_unlink((const char*)arg1); + break; default: dwarnln("Unknown syscall {}", syscall); break; diff --git a/libc/include/sys/syscall.h b/libc/include/sys/syscall.h index 0daa6d7a..b6eacdf8 100644 --- a/libc/include/sys/syscall.h +++ b/libc/include/sys/syscall.h @@ -58,6 +58,7 @@ __BEGIN_DECLS #define SYS_CHMOD 55 #define SYS_CREATE 56 // creat, mkfifo #define SYS_CREATE_DIR 57 // mkdir +#define SYS_UNLINK 58 __END_DECLS diff --git a/libc/unistd.cpp b/libc/unistd.cpp index b334b4d4..b118da95 100644 --- a/libc/unistd.cpp +++ b/libc/unistd.cpp @@ -210,6 +210,11 @@ void syncsync(int should_block) syscall(SYS_SYNC, should_block); } +int unlink(const char* path) +{ + return syscall(SYS_UNLINK, path); +} + pid_t getpid(void) { return syscall(SYS_GET_PID);