summaryrefslogtreecommitdiff
path: root/Kernel
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
parenta5514fece9cc15738bf41d579b203630c809fe8e (diff)
downloadserenity-bc7c8879c5d3230c0caf3ea922446e27c6f77cbc.zip
Kernel+LibC+LibCore: Implement the unlinkat(2) syscall
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/API/POSIX/fcntl.h1
-rw-r--r--Kernel/Process.h2
-rw-r--r--Kernel/Syscalls/unlink.cpp21
3 files changed, 21 insertions, 3 deletions
diff --git a/Kernel/API/POSIX/fcntl.h b/Kernel/API/POSIX/fcntl.h
index b28cefb678..2a8bdfca5c 100644
--- a/Kernel/API/POSIX/fcntl.h
+++ b/Kernel/API/POSIX/fcntl.h
@@ -46,6 +46,7 @@ extern "C" {
#define AT_FDCWD -100
#define AT_SYMLINK_NOFOLLOW 0x100
+#define AT_REMOVEDIR 0x200
struct flock {
short l_type;
diff --git a/Kernel/Process.h b/Kernel/Process.h
index 0f83fee862..195ef0b3d9 100644
--- a/Kernel/Process.h
+++ b/Kernel/Process.h
@@ -354,7 +354,7 @@ public:
ErrorOr<FlatPtr> sys$times(Userspace<tms*>);
ErrorOr<FlatPtr> sys$utime(Userspace<char const*> pathname, size_t path_length, Userspace<const struct utimbuf*>);
ErrorOr<FlatPtr> sys$link(Userspace<Syscall::SC_link_params const*>);
- ErrorOr<FlatPtr> sys$unlink(Userspace<char const*> pathname, size_t path_length);
+ ErrorOr<FlatPtr> sys$unlink(int dirfd, Userspace<char const*> pathname, size_t path_length, int flags);
ErrorOr<FlatPtr> sys$symlink(Userspace<Syscall::SC_symlink_params const*>);
ErrorOr<FlatPtr> sys$rmdir(Userspace<char const*> pathname, size_t path_length);
ErrorOr<FlatPtr> sys$mount(Userspace<Syscall::SC_mount_params const*>);
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;
}