From 3666525d24f42bb35fca424ea9b3ce0528916945 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Tue, 17 Sep 2024 16:38:15 +0300 Subject: [PATCH] Kernel/LibC: Implement `readlink` in terms of `readlinkat` --- kernel/include/kernel/Process.h | 2 - kernel/kernel/Process.cpp | 41 ++++++++----------- .../libraries/LibC/include/sys/syscall.h | 1 - userspace/libraries/LibC/unistd.cpp | 3 +- 4 files changed, 18 insertions(+), 29 deletions(-) diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 82ad05e0..f7c98169 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -109,8 +109,6 @@ namespace Kernel BAN::ErrorOr sys_access(const char* path, int amode); BAN::ErrorOr sys_create_dir(const char*, mode_t); BAN::ErrorOr sys_unlink(const char*); - BAN::ErrorOr readlink_impl(BAN::RefPtr, char* buffer, size_t bufsize); - BAN::ErrorOr sys_readlink(const char* path, char* buffer, size_t bufsize); BAN::ErrorOr sys_readlinkat(int fd, const char* path, char* buffer, size_t bufsize); BAN::ErrorOr sys_pread(int fd, void* buffer, size_t count, off_t offset); diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 819a9e14..784cbbf1 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -994,37 +994,28 @@ namespace Kernel return 0; } - BAN::ErrorOr Process::readlink_impl(BAN::RefPtr inode, char* buffer, size_t bufsize) - { - // FIXME: no allocation needed - auto link_target = TRY(inode->link_target()); - - size_t byte_count = BAN::Math::min(link_target.size(), bufsize); - memcpy(buffer, link_target.data(), byte_count); - - return byte_count; - } - - BAN::ErrorOr Process::sys_readlink(const char* path, char* buffer, size_t bufsize) - { - LockGuard _(m_process_lock); - TRY(validate_string_access(path)); - TRY(validate_pointer_access(buffer, bufsize, true)); - - auto absolute_path = TRY(absolute_path_of(path)); - auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, O_NOFOLLOW | O_RDONLY)); - return readlink_impl(file.inode, buffer, bufsize); - } - BAN::ErrorOr Process::sys_readlinkat(int fd, const char* path, char* buffer, size_t bufsize) { LockGuard _(m_process_lock); TRY(validate_string_access(path)); TRY(validate_pointer_access(buffer, bufsize, true)); - auto parent_file = TRY(m_open_file_descriptors.file_of(fd)); - auto file = TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, O_NOFOLLOW | O_RDONLY)); - return readlink_impl(file.inode, buffer, bufsize); + VirtualFileSystem::File parent_file; + if (path[0] == '/') + parent_file = VirtualFileSystem::get().root_file(); + else if (fd == AT_FDCWD) + parent_file = TRY(m_working_directory.clone()); + else + parent_file = TRY(m_open_file_descriptors.file_of(fd)); + + auto inode = TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, O_NOFOLLOW | O_RDONLY)).inode; + + // FIXME: no allocation needed + auto link_target = TRY(inode->link_target()); + + const size_t byte_count = BAN::Math::min(link_target.size(), bufsize); + memcpy(buffer, link_target.data(), byte_count); + return byte_count; } BAN::ErrorOr Process::sys_pread(int fd, void* buffer, size_t count, off_t offset) diff --git a/userspace/libraries/LibC/include/sys/syscall.h b/userspace/libraries/LibC/include/sys/syscall.h index e4190818..071c70c7 100644 --- a/userspace/libraries/LibC/include/sys/syscall.h +++ b/userspace/libraries/LibC/include/sys/syscall.h @@ -55,7 +55,6 @@ __BEGIN_DECLS O(SYS_FCHMOD, fchmod) \ O(SYS_CREATE_DIR, create_dir) \ O(SYS_UNLINK, unlink) \ - O(SYS_READLINK, readlink) \ O(SYS_READLINKAT, readlinkat) \ O(SYS_MSYNC, msync) \ O(SYS_PREAD, pread) \ diff --git a/userspace/libraries/LibC/unistd.cpp b/userspace/libraries/LibC/unistd.cpp index 48639ce0..62493da1 100644 --- a/userspace/libraries/LibC/unistd.cpp +++ b/userspace/libraries/LibC/unistd.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -86,7 +87,7 @@ ssize_t write(int fildes, const void* buf, size_t nbyte) ssize_t readlink(const char* __restrict path, char* __restrict buf, size_t bufsize) { - return syscall(SYS_READLINK, path, buf, bufsize); + return readlinkat(AT_FDCWD, path, buf, bufsize); } ssize_t readlinkat(int fd, const char* __restrict path, char* __restrict buf, size_t bufsize)