From 1e6719abe9f90a71dc0a58537b93bc38fc89c5de Mon Sep 17 00:00:00 2001 From: Andrei Tatar Date: Wed, 27 Mar 2024 15:37:31 +0100 Subject: [PATCH] lib/posix-fdio: Add internal futime(n)s syscalls This change adds internal API variants of futimes and futimens. Checkpatch-Ignore: MACRO_ARG_REUSE Signed-off-by: Andrei Tatar Approved-by: Sergiu Moga Reviewed-by: Sergiu Moga GitHub-Closes: #1575 --- lib/posix-fdio/Config.uk | 2 + lib/posix-fdio/fdstat.c | 67 ++++++++++++++++++++++++++ lib/posix-fdio/include/uk/posix-fdio.h | 5 ++ 3 files changed, 74 insertions(+) diff --git a/lib/posix-fdio/Config.uk b/lib/posix-fdio/Config.uk index e11a933ac..47264a8a5 100644 --- a/lib/posix-fdio/Config.uk +++ b/lib/posix-fdio/Config.uk @@ -2,5 +2,7 @@ config LIBPOSIX_FDIO bool "posix-fdio: File I/O and control" select LIBUKATOMIC select LIBUKFILE + select LIBPOSIX_TIME + select LIBUKTIMECONV select LIBPOSIX_FDTAB select LIBPOSIX_FDTAB_LEGACY_SHIM diff --git a/lib/posix-fdio/fdstat.c b/lib/posix-fdio/fdstat.c index 80d653043..8638c3416 100644 --- a/lib/posix-fdio/fdstat.c +++ b/lib/posix-fdio/fdstat.c @@ -9,9 +9,16 @@ #include #include +#include +#include #include "fdio-impl.h" +#define statx_time(ts) ((struct uk_statx_timestamp){ \ + .tv_sec = (ts).tv_sec, \ + .tv_nsec = (ts).tv_nsec \ +}) + static inline dev_t nums2dev(__u32 major, __u32 minor) { @@ -117,3 +124,63 @@ int uk_sys_fchown(struct uk_ofile *of, uid_t owner, gid_t group) uk_file_wunlock(of->file); return r; } + +int uk_sys_futimens(struct uk_ofile *of, const struct timespec *times) +{ + int r; + unsigned int mask; + struct uk_statx sx; + struct timespec t; + const int iolock = _SHOULD_LOCK(of->mode); + + /* TODO: check if uid is root or file owner for custom times */ + + if (!times || + times[0].tv_nsec == UTIME_NOW || times[1].tv_nsec == UTIME_NOW) { + r = uk_sys_clock_gettime(CLOCK_REALTIME, &t); + if (unlikely(r)) { + UK_ASSERT(r < 0); + /* The futime(n)s manpages do not specify an error case + * for failing to get the current time, and failure of + * the above call may indicate a misconfigured kernel. + * Print a warning before erroring out. + */ + uk_pr_warn("Failed to get current time: %d\n", r); + return r; + } + } + + if (!times) { + mask = UK_STATX_ATIME | UK_STATX_MTIME; + sx.stx_atime = statx_time(t); + sx.stx_mtime = statx_time(t); + } else { + mask = 0; + if (times[0].tv_nsec != UTIME_OMIT) { + mask |= UK_STATX_ATIME; + if (times[0].tv_nsec == UTIME_NOW) + sx.stx_atime = statx_time(t); + else + sx.stx_atime = statx_time(times[0]); + } + if (times[1].tv_nsec != UTIME_OMIT) { + mask |= UK_STATX_MTIME; + if (times[1].tv_nsec == UTIME_NOW) + sx.stx_mtime = statx_time(t); + else + sx.stx_mtime = statx_time(times[1]); + } + } + + if (iolock) + uk_file_wlock(of->file); + r = uk_file_setstat(of->file, mask, &sx); + if (iolock) + uk_file_wunlock(of->file); + return r; +} + +int uk_sys_futimes(struct uk_ofile *of, const struct timeval *tv) +{ + return uk_sys_futimens(of, tv ? &uk_time_spec_from_val(tv) : NULL); +} diff --git a/lib/posix-fdio/include/uk/posix-fdio.h b/lib/posix-fdio/include/uk/posix-fdio.h index e05182458..4ee445ece 100644 --- a/lib/posix-fdio/include/uk/posix-fdio.h +++ b/lib/posix-fdio/include/uk/posix-fdio.h @@ -10,6 +10,7 @@ #define __UK_POSIX_FDIO_H__ #include +#include #include @@ -67,6 +68,10 @@ int uk_sys_fchmod(struct uk_ofile *of, mode_t mode); int uk_sys_fchown(struct uk_ofile *of, uid_t owner, gid_t group); +int uk_sys_futimes(struct uk_ofile *of, const struct timeval *tv); + +int uk_sys_futimens(struct uk_ofile *of, const struct timespec *times); + /* Control */ int uk_sys_ioctl(struct uk_ofile *of, int cmd, void *arg); -- 2.39.5