summaryrefslogtreecommitdiff
path: root/Kernel/Syscalls/unlink.cpp
diff options
context:
space:
mode:
authorsin-ack <sin-ack@users.noreply.github.com>2022-02-10 11:30:33 +0000
committerBrian Gianforcaro <b.gianfo@gmail.com>2022-04-23 10:43:32 -0700
commitbc7c8879c5d3230c0caf3ea922446e27c6f77cbc (patch)
treeafcd145a2ceb9a105836e3a5facd4e651b612c8d /Kernel/Syscalls/unlink.cpp
parenta5514fece9cc15738bf41d579b203630c809fe8e (diff)
downloadserenity-bc7c8879c5d3230c0caf3ea922446e27c6f77cbc.zip
Kernel+LibC+LibCore: Implement the unlinkat(2) syscall
Diffstat (limited to 'Kernel/Syscalls/unlink.cpp')
-rw-r--r--Kernel/Syscalls/unlink.cpp21
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;
}