diff options
author | circl <circl.lastname@gmail.com> | 2021-12-31 19:20:17 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-01-01 15:08:49 +0100 |
commit | 63760603f3adec2fb696018f6c1c77feeb0dbdd0 (patch) | |
tree | 3d96a31951e538ab9cdc3c99b025ff5c9a41bb42 /Kernel/Syscalls/chown.cpp | |
parent | 344cfa0db4a76601754aead153fa52d2cde6db1e (diff) | |
download | serenity-63760603f3adec2fb696018f6c1c77feeb0dbdd0.zip |
Kernel+LibC+LibCore: Add lchown and fchownat functions
This modifies sys$chown to allow specifying whether or not to follow
symlinks and in which directory.
This was then used to implement lchown and fchownat in LibC and LibCore.
Diffstat (limited to 'Kernel/Syscalls/chown.cpp')
-rw-r--r-- | Kernel/Syscalls/chown.cpp | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/Kernel/Syscalls/chown.cpp b/Kernel/Syscalls/chown.cpp index 92172fed61..0db2c9cccc 100644 --- a/Kernel/Syscalls/chown.cpp +++ b/Kernel/Syscalls/chown.cpp @@ -4,6 +4,8 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <AK/NonnullRefPtrVector.h> +#include <Kernel/FileSystem/Custody.h> #include <Kernel/FileSystem/OpenFileDescription.h> #include <Kernel/Process.h> @@ -24,7 +26,18 @@ ErrorOr<FlatPtr> Process::sys$chown(Userspace<const Syscall::SC_chown_params*> u TRY(require_promise(Pledge::chown)); auto params = TRY(copy_typed_from_user(user_params)); auto path = TRY(get_syscall_path_argument(params.path)); - TRY(VirtualFileSystem::the().chown(path->view(), params.uid, params.gid, current_directory())); + + RefPtr<Custody> base; + if (params.dirfd == AT_FDCWD) { + base = current_directory(); + } else { + auto base_description = TRY(fds().open_file_description(params.dirfd)); + if (!base_description->custody()) + return EINVAL; + base = base_description->custody(); + } + + TRY(VirtualFileSystem::the().chown(path->view(), params.uid, params.gid, *base, params.follow_symlinks ? 0 : O_NOFOLLOW_NOERROR)); return 0; } |