Kernel+LibC+LibCore: Implement the unlinkat(2) syscall

This commit is contained in:
sin-ack 2022-02-10 11:30:33 +00:00 committed by Brian Gianforcaro
parent a5514fece9
commit bc7c8879c5
Notes: sideshowbarker 2024-07-17 11:35:08 +09:00
7 changed files with 31 additions and 6 deletions

View file

@ -46,6 +46,7 @@ extern "C" {
#define AT_FDCWD -100
#define AT_SYMLINK_NOFOLLOW 0x100
#define AT_REMOVEDIR 0x200
struct flock {
short l_type;

View file

@ -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*>);

View file

@ -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;
}

View file

@ -362,7 +362,7 @@ int Emulator::virt$rmdir(FlatPtr path, size_t path_length)
int Emulator::virt$unlink(FlatPtr path, size_t path_length)
{
auto buffer = mmu().copy_buffer_from_vm(path, path_length);
return syscall(SC_unlink, buffer.data(), buffer.size());
return syscall(SC_unlink, AT_FDCWD, buffer.data(), buffer.size(), 0);
}
int Emulator::virt$symlink(FlatPtr params_addr)

View file

@ -644,7 +644,13 @@ int link(char const* old_path, char const* new_path)
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html
int unlink(char const* pathname)
{
int rc = syscall(SC_unlink, pathname, strlen(pathname));
return unlinkat(AT_FDCWD, pathname, 0);
}
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlinkat.html
int unlinkat(int dirfd, char const* pathname, int flags)
{
int rc = syscall(SC_unlink, dirfd, pathname, strlen(pathname), flags);
__RETURN_WITH_ERRNO(rc, rc, -1);
}

View file

@ -92,6 +92,7 @@ int ttyname_r(int fd, char* buffer, size_t);
off_t lseek(int fd, off_t, int whence);
int link(char const* oldpath, char const* newpath);
int unlink(char const* pathname);
int unlinkat(int dirfd, char const* pathname, int flags);
int symlink(char const* target, char const* linkpath);
int rmdir(char const* pathname);
int dup(int old_fd);

View file

@ -854,7 +854,7 @@ ErrorOr<void> unlink(StringView path)
return Error::from_errno(EFAULT);
#ifdef __serenity__
int rc = syscall(SC_unlink, path.characters_without_null_termination(), path.length());
int rc = syscall(SC_unlink, AT_FDCWD, path.characters_without_null_termination(), path.length(), 0);
HANDLE_SYSCALL_RETURN_VALUE("unlink"sv, rc, {});
#else
String path_string = path;