diff --git a/Kernel/API/Syscall.h b/Kernel/API/Syscall.h index 114a159c2b9..171c7815302 100644 --- a/Kernel/API/Syscall.h +++ b/Kernel/API/Syscall.h @@ -417,6 +417,7 @@ struct SC_mknod_params { StringArgument path; u16 mode; dev_t dev; + int dirfd; }; struct SC_symlink_params { diff --git a/Kernel/Syscalls/mknod.cpp b/Kernel/Syscalls/mknod.cpp index 45f558cb523..1870c6cde89 100644 --- a/Kernel/Syscalls/mknod.cpp +++ b/Kernel/Syscalls/mknod.cpp @@ -20,7 +20,7 @@ ErrorOr Process::sys$mknod(Userspace u if (!credentials->is_superuser() && !is_regular_file(params.mode) && !is_fifo(params.mode) && !is_socket(params.mode)) return EPERM; auto path = TRY(get_syscall_path_argument(params.path)); - TRY(VirtualFileSystem::the().mknod(credentials, path->view(), params.mode & ~umask(), params.dev, current_directory())); + TRY(VirtualFileSystem::the().mknod(credentials, path->view(), params.mode & ~umask(), params.dev, TRY(custody_for_dirfd(params.dirfd)))); return 0; } diff --git a/Userland/Libraries/LibC/unistd.cpp b/Userland/Libraries/LibC/unistd.cpp index 867b53b5ba9..06b7a09eba8 100644 --- a/Userland/Libraries/LibC/unistd.cpp +++ b/Userland/Libraries/LibC/unistd.cpp @@ -828,12 +828,18 @@ int faccessat(int dirfd, char const* pathname, int mode, int flags) // https://pubs.opengroup.org/onlinepubs/9699919799/functions/mknod.html int mknod(char const* pathname, mode_t mode, dev_t dev) +{ + return mknodat(AT_FDCWD, pathname, mode, dev); +} + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/mknodat.html +int mknodat(int dirfd, char const* pathname, mode_t mode, dev_t dev) { if (!pathname) { errno = EFAULT; return -1; } - Syscall::SC_mknod_params params { { pathname, strlen(pathname) }, mode, dev }; + Syscall::SC_mknod_params params { { pathname, strlen(pathname) }, mode, dev, dirfd }; int rc = syscall(SC_mknod, ¶ms); __RETURN_WITH_ERRNO(rc, rc, -1); } diff --git a/Userland/Libraries/LibC/unistd.h b/Userland/Libraries/LibC/unistd.h index 75b67f90a73..0ecea2b36cb 100644 --- a/Userland/Libraries/LibC/unistd.h +++ b/Userland/Libraries/LibC/unistd.h @@ -108,6 +108,7 @@ int access(char const* pathname, int mode); int faccessat(int dirfd, char const* pathname, int mode, int flags); int isatty(int fd); int mknod(char const* pathname, mode_t, dev_t); +int mknodat(int dirfd, char const* pathname, mode_t, dev_t); long fpathconf(int fd, int name); long pathconf(char const* path, int name); char* getlogin(void); diff --git a/Userland/Libraries/LibCore/System.cpp b/Userland/Libraries/LibCore/System.cpp index aa6eb7d999e..9b7ee12bb4a 100644 --- a/Userland/Libraries/LibCore/System.cpp +++ b/Userland/Libraries/LibCore/System.cpp @@ -1622,7 +1622,7 @@ ErrorOr mknod(StringView pathname, mode_t mode, dev_t dev) return Error::from_syscall("mknod"sv, -EFAULT); #ifdef AK_OS_SERENITY - Syscall::SC_mknod_params params { { pathname.characters_without_null_termination(), pathname.length() }, mode, dev }; + Syscall::SC_mknod_params params { { pathname.characters_without_null_termination(), pathname.length() }, mode, dev, AT_FDCWD }; int rc = syscall(SC_mknod, ¶ms); HANDLE_SYSCALL_RETURN_VALUE("mknod", rc, {}); #else