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 | |
parent | a5514fece9cc15738bf41d579b203630c809fe8e (diff) | |
download | serenity-bc7c8879c5d3230c0caf3ea922446e27c6f77cbc.zip |
Kernel+LibC+LibCore: Implement the unlinkat(2) syscall
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/API/POSIX/fcntl.h | 1 | ||||
-rw-r--r-- | Kernel/Process.h | 2 | ||||
-rw-r--r-- | Kernel/Syscalls/unlink.cpp | 21 |
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; } |