summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibC
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2023-04-08 11:39:28 +0300
committerAndreas Kling <kling@serenityos.org>2023-04-10 10:21:28 +0200
commitd05d938e738fa2b0de0b5e1412384a0b843b4863 (patch)
treefd07dfe22a7835e69afe143b5476b2992b4f7134 /Userland/Libraries/LibC
parentcbf78975f14ac60dfaa7f712fb35f8651567f39e (diff)
downloadserenity-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.h18
-rw-r--r--Userland/Libraries/LibC/fcntl.cpp28
-rw-r--r--Userland/Libraries/LibC/stat.cpp3
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, &params);
+ 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, &params);
+ } else {
+ Syscall::SC_futimens_params params { fd, times };
+ rc = syscall(SC_futimens, &params);
+ }
+
__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);
}
}