From 580a94bc44bcea61bf1b07abf24c1b00e43a1d64 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 10 Feb 2020 19:32:40 +0100 Subject: [PATCH] Kernel+LibC: Merge sys$stat() and sys$lstat() There is now only one sys$stat() instead of two separate syscalls. --- Kernel/Process.cpp | 30 +++++++----------------------- Kernel/Process.h | 3 +-- Kernel/Syscall.h | 7 ++++++- Libraries/LibC/unistd.cpp | 17 +++++++++-------- 4 files changed, 23 insertions(+), 34 deletions(-) diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 6ee08c341ac170..5755cd1ab4a6fb 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1783,41 +1783,25 @@ int Process::sys$fstat(int fd, stat* statbuf) return description->fstat(*statbuf); } -int Process::sys$lstat(const char* user_path, size_t path_length, stat* user_statbuf) +int Process::sys$stat(const Syscall::SC_stat_params* user_params) { REQUIRE_PROMISE(rpath); - if (!validate_write_typed(user_statbuf)) + Syscall::SC_stat_params params; + if (!validate_read_and_copy_typed(¶ms, user_params)) return -EFAULT; - auto path = get_syscall_path_argument(user_path, path_length); - if (path.is_error()) - return path.error(); - auto metadata_or_error = VFS::the().lookup_metadata(path.value(), current_directory(), O_NOFOLLOW_NOERROR); - if (metadata_or_error.is_error()) - return metadata_or_error.error(); - stat statbuf; - auto result = metadata_or_error.value().stat(statbuf); - if (result.is_error()) - return result; - copy_to_user(user_statbuf, &statbuf); - return 0; -} - -int Process::sys$stat(const char* user_path, size_t path_length, stat* user_statbuf) -{ - REQUIRE_PROMISE(rpath); - if (!validate_write_typed(user_statbuf)) + if (!validate_write_typed(params.statbuf)) return -EFAULT; - auto path = get_syscall_path_argument(user_path, path_length); + auto path = get_syscall_path_argument(params.path); if (path.is_error()) return path.error(); - auto metadata_or_error = VFS::the().lookup_metadata(path.value(), current_directory()); + auto metadata_or_error = VFS::the().lookup_metadata(path.value(), current_directory(), params.follow_symlinks ? 0 : O_NOFOLLOW_NOERROR); if (metadata_or_error.is_error()) return metadata_or_error.error(); stat statbuf; auto result = metadata_or_error.value().stat(statbuf); if (result.is_error()) return result; - copy_to_user(user_statbuf, &statbuf); + copy_to_user(params.statbuf, &statbuf); return 0; } diff --git a/Kernel/Process.h b/Kernel/Process.h index e9156e42096fff..01c7c5d3f668f9 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -195,8 +195,7 @@ class Process : public InlineLinkedListNode ssize_t sys$write(int fd, const u8*, ssize_t); ssize_t sys$writev(int fd, const struct iovec* iov, int iov_count); int sys$fstat(int fd, stat*); - int sys$lstat(const char*, size_t, stat*); - int sys$stat(const char*, size_t, stat*); + int sys$stat(const Syscall::SC_stat_params*); int sys$lseek(int fd, off_t, int whence); int sys$kill(pid_t pid, int sig); [[noreturn]] void sys$exit(int status); diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index 41392023da3b5d..75e8cf79908ad1 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -56,7 +56,6 @@ typedef u32 socklen_t; __ENUMERATE_SYSCALL(mmap) \ __ENUMERATE_SYSCALL(munmap) \ __ENUMERATE_SYSCALL(get_dir_entries) \ - __ENUMERATE_SYSCALL(lstat) \ __ENUMERATE_SYSCALL(getcwd) \ __ENUMERATE_SYSCALL(gettimeofday) \ __ENUMERATE_SYSCALL(gethostname) \ @@ -413,6 +412,12 @@ struct SC_waitid_params { int options; }; +struct SC_stat_params { + StringArgument path; + struct stat* statbuf; + bool follow_symlinks; +}; + void initialize(); int sync(); diff --git a/Libraries/LibC/unistd.cpp b/Libraries/LibC/unistd.cpp index 4a1d6b1e466224..81769a2996d3b8 100644 --- a/Libraries/LibC/unistd.cpp +++ b/Libraries/LibC/unistd.cpp @@ -278,24 +278,25 @@ int close(int fd) __RETURN_WITH_ERRNO(rc, rc, -1); } -int lstat(const char* path, struct stat* statbuf) +static int do_stat(const char* path, struct stat* statbuf, bool follow_symlinks) { if (!path) { errno = EFAULT; return -1; } - int rc = syscall(SC_lstat, path, strlen(path), statbuf); + Syscall::SC_stat_params params { { path, strlen(path) }, statbuf, follow_symlinks }; + int rc = syscall(SC_stat, ¶ms); __RETURN_WITH_ERRNO(rc, rc, -1); } +int lstat(const char* path, struct stat* statbuf) +{ + return do_stat(path, statbuf, false); +} + int stat(const char* path, struct stat* statbuf) { - if (!path) { - errno = EFAULT; - return -1; - } - int rc = syscall(SC_stat, path, strlen(path), statbuf); - __RETURN_WITH_ERRNO(rc, rc, -1); + return do_stat(path, statbuf, true); } int fstat(int fd, struct stat* statbuf)