diff options
author | Liav A <liavalb@gmail.com> | 2023-04-08 11:39:28 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-04-10 10:21:28 +0200 |
commit | d05d938e738fa2b0de0b5e1412384a0b843b4863 (patch) | |
tree | fd07dfe22a7835e69afe143b5476b2992b4f7134 /Userland/Libraries/LibC | |
parent | cbf78975f14ac60dfaa7f712fb35f8651567f39e (diff) | |
download | serenity-d05d938e738fa2b0de0b5e1412384a0b843b4863.zip |
LibC: Properly implement the futimens function
Use the new futimens syscall to ensure futimens can actually work.
This change for example allows a user to run "touch non-existing-file"
without getting any error, as expected.
Diffstat (limited to 'Userland/Libraries/LibC')
-rw-r--r-- | Userland/Libraries/LibC/bits/utimens.h | 18 | ||||
-rw-r--r-- | Userland/Libraries/LibC/fcntl.cpp | 28 | ||||
-rw-r--r-- | Userland/Libraries/LibC/stat.cpp | 3 |
3 files changed, 42 insertions, 7 deletions
diff --git a/Userland/Libraries/LibC/bits/utimens.h b/Userland/Libraries/LibC/bits/utimens.h new file mode 100644 index 0000000000..649acedda5 --- /dev/null +++ b/Userland/Libraries/LibC/bits/utimens.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2018-2022, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2021, sin-ack <sin-ack@protonmail.com> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <Kernel/API/POSIX/fcntl.h> +#include <Kernel/API/POSIX/sys/stat.h> +#include <sys/cdefs.h> + +__BEGIN_DECLS + +int __utimens(int fd, char const* path, struct timespec const times[2], int flag); + +__END_DECLS diff --git a/Userland/Libraries/LibC/fcntl.cpp b/Userland/Libraries/LibC/fcntl.cpp index 8a8ab0f11f..4857ded2d5 100644 --- a/Userland/Libraries/LibC/fcntl.cpp +++ b/Userland/Libraries/LibC/fcntl.cpp @@ -6,6 +6,7 @@ */ #include <bits/pthread_cancel.h> +#include <bits/utimens.h> #include <errno.h> #include <fcntl.h> #include <limits.h> @@ -127,11 +128,18 @@ int utimensat(int dirfd, char const* path, struct timespec const times[2], int f errno = EFAULT; return -1; } + return __utimens(dirfd, path, times, flag); +} - size_t path_length = strlen(path); - if (path_length > INT32_MAX) { - errno = EINVAL; - return -1; +int __utimens(int fd, char const* path, struct timespec const times[2], int flag) +{ + size_t path_length = 0; + if (path) { + path_length = strlen(path); + if (path_length > INT32_MAX) { + errno = EINVAL; + return -1; + } } // POSIX allows AT_SYMLINK_NOFOLLOW flag or no flags. @@ -161,8 +169,16 @@ int utimensat(int dirfd, char const* path, struct timespec const times[2], int f } } - Syscall::SC_utimensat_params params { dirfd, { path, path_length }, times, flag }; - int rc = syscall(SC_utimensat, ¶ms); + int rc = 0; + if (path) { + // NOTE: fd is treated as dirfd for this syscall. + Syscall::SC_utimensat_params params { fd, { path, path_length }, times, flag }; + rc = syscall(SC_utimensat, ¶ms); + } else { + Syscall::SC_futimens_params params { fd, times }; + rc = syscall(SC_futimens, ¶ms); + } + __RETURN_WITH_ERRNO(rc, rc, -1); } } diff --git a/Userland/Libraries/LibC/stat.cpp b/Userland/Libraries/LibC/stat.cpp index 10c95b1d26..c6139a602a 100644 --- a/Userland/Libraries/LibC/stat.cpp +++ b/Userland/Libraries/LibC/stat.cpp @@ -5,6 +5,7 @@ */ #include <assert.h> +#include <bits/utimens.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> @@ -119,6 +120,6 @@ int fstatat(int fd, char const* path, struct stat* statbuf, int flags) // https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html int futimens(int fd, struct timespec const times[2]) { - return utimensat(fd, "", times, 0); + return __utimens(fd, nullptr, times, 0); } } |