From b8c847a3cdb948f057158cc47a4602ee99168c33 Mon Sep 17 00:00:00 2001 From: Emily Trau Date: Mon, 5 Jun 2023 17:46:36 -0700 Subject: [PATCH] LibC: Add `lutimes(2)` and `futimes(2)` implementations Needed for a port of nix --- Userland/Libraries/LibC/sys/time.h | 4 +++- Userland/Libraries/LibC/time.cpp | 30 +++++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibC/sys/time.h b/Userland/Libraries/LibC/sys/time.h index 59e2329b81..00d741f6e9 100644 --- a/Userland/Libraries/LibC/sys/time.h +++ b/Userland/Libraries/LibC/sys/time.h @@ -20,7 +20,9 @@ struct timezone { int adjtime(const struct timeval* delta, struct timeval* old_delta); int gettimeofday(struct timeval* __restrict__, void* __restrict__); int settimeofday(struct timeval* __restrict__, void* __restrict__); -int utimes(char const* pathname, const struct timeval[2]); +int utimes(char const* pathname, struct timeval const times[2]); +int lutimes(char const* pathname, struct timeval const times[2]); +int futimes(int fd, struct timeval const times[2]); static inline void timeradd(const struct timeval* a, const struct timeval* b, struct timeval* out) { diff --git a/Userland/Libraries/LibC/time.cpp b/Userland/Libraries/LibC/time.cpp index 127ccf152f..04e44987f8 100644 --- a/Userland/Libraries/LibC/time.cpp +++ b/Userland/Libraries/LibC/time.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -77,16 +78,39 @@ int settimeofday(struct timeval* __restrict__ tv, void* __restrict__) return clock_settime(CLOCK_REALTIME, &ts); } -int utimes(char const* pathname, const struct timeval times[2]) +int utimes(char const* pathname, struct timeval const times[2]) { - if (!times) { + if (!times) return utime(pathname, nullptr); - } // FIXME: implement support for tv_usec in the utime (or a new) syscall utimbuf buf = { times[0].tv_sec, times[1].tv_sec }; return utime(pathname, &buf); } +// Not in POSIX, originated in BSD but also supported on Linux. +// https://man.netbsd.org/NetBSD-6.0/lutimes.2 +int lutimes(char const* pathname, struct timeval const times[2]) +{ + if (!times) + return utimensat(AT_FDCWD, pathname, nullptr, AT_SYMLINK_NOFOLLOW); + timespec ts[2]; + TIMEVAL_TO_TIMESPEC(×[0], &ts[0]); + TIMEVAL_TO_TIMESPEC(×[1], &ts[1]); + return utimensat(AT_FDCWD, pathname, ts, AT_SYMLINK_NOFOLLOW); +} + +// Not in POSIX, originated in BSD but also supported on Linux. +// https://man.netbsd.org/NetBSD-6.0/futimes.2 +int futimes(int fd, struct timeval const times[2]) +{ + if (!times) + return utimensat(fd, nullptr, nullptr, 0); + timespec ts[2]; + TIMEVAL_TO_TIMESPEC(×[0], &ts[0]); + TIMEVAL_TO_TIMESPEC(×[1], &ts[1]); + return utimensat(fd, nullptr, ts, 0); +} + char* ctime(time_t const* t) { return asctime(localtime(t));