summaryrefslogtreecommitdiff
path: root/Kernel/Syscalls/chown.cpp
diff options
context:
space:
mode:
authorcircl <circl.lastname@gmail.com>2021-12-31 19:20:17 +0100
committerAndreas Kling <kling@serenityos.org>2022-01-01 15:08:49 +0100
commit63760603f3adec2fb696018f6c1c77feeb0dbdd0 (patch)
tree3d96a31951e538ab9cdc3c99b025ff5c9a41bb42 /Kernel/Syscalls/chown.cpp
parent344cfa0db4a76601754aead153fa52d2cde6db1e (diff)
downloadserenity-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.cpp15
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;
}