diff options
author | sin-ack <sin-ack@users.noreply.github.com> | 2022-02-10 11:30:33 +0000 |
---|---|---|
committer | Brian Gianforcaro <b.gianfo@gmail.com> | 2022-04-23 10:43:32 -0700 |
commit | bc7c8879c5d3230c0caf3ea922446e27c6f77cbc (patch) | |
tree | afcd145a2ceb9a105836e3a5facd4e651b612c8d /Kernel/Syscalls/unlink.cpp | |
parent | a5514fece9cc15738bf41d579b203630c809fe8e (diff) | |
download | serenity-bc7c8879c5d3230c0caf3ea922446e27c6f77cbc.zip |
Kernel+LibC+LibCore: Implement the unlinkat(2) syscall
Diffstat (limited to 'Kernel/Syscalls/unlink.cpp')
-rw-r--r-- | Kernel/Syscalls/unlink.cpp | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/Kernel/Syscalls/unlink.cpp b/Kernel/Syscalls/unlink.cpp index 80c89518db..582b1bea58 100644 --- a/Kernel/Syscalls/unlink.cpp +++ b/Kernel/Syscalls/unlink.cpp @@ -10,12 +10,29 @@ namespace Kernel { -ErrorOr<FlatPtr> Process::sys$unlink(Userspace<char const*> user_path, size_t path_length) +ErrorOr<FlatPtr> Process::sys$unlink(int dirfd, Userspace<char const*> user_path, size_t path_length, int flags) { VERIFY_NO_PROCESS_BIG_LOCK(this) TRY(require_promise(Pledge::cpath)); auto path = TRY(get_syscall_path_argument(user_path, path_length)); - TRY(VirtualFileSystem::the().unlink(path->view(), current_directory())); + + if (flags & ~AT_REMOVEDIR) + return Error::from_errno(EINVAL); + + RefPtr<Custody> base; + if (dirfd == AT_FDCWD) { + base = current_directory(); + } else { + auto base_description = TRY(open_file_description(dirfd)); + if (!base_description->custody()) + return Error::from_errno(EINVAL); + base = base_description->custody(); + } + + if (flags & AT_REMOVEDIR) + TRY(VirtualFileSystem::the().rmdir(path->view(), *base)); + else + TRY(VirtualFileSystem::the().unlink(path->view(), *base)); return 0; } |