diff --git a/src/libfaketime.c b/src/libfaketime.c index eadd6b4..a6651c5 100644 --- a/src/libfaketime.c +++ b/src/libfaketime.c @@ -333,6 +333,8 @@ static pthread_once_t initialized_once_control = PTHREAD_ONCE_INIT; /* prototypes */ static int fake_gettimeofday(struct timeval *tv); static int fake_clock_gettime(clockid_t clk_id, struct timespec *tp); +static int fake_current_realtime(struct timespec *tp); +static int fake_current_timeval(struct timeval *tv); int read_config_file(); bool str_array_contains(const char *haystack, const char *needle); void *ft_dlvsym(void *handle, const char *symbol, const char *version, const char *full_name, char *ignore_list, bool should_debug_dlsym); @@ -1296,7 +1298,12 @@ int utime(const char *filename, const struct utimbuf *times) { if (times == NULL) { /* The user wants their given fake times left alone but they requested NOW, so turn it into fake NOW */ - ntbuf.actime = ntbuf.modtime = time(NULL); + struct timespec now; + if (fake_current_realtime(&now) == -1) + { + return -1; + } + ntbuf.actime = ntbuf.modtime = now.tv_sec; times = &ntbuf; } } @@ -1329,7 +1336,10 @@ int utimes(const char *filename, const struct timeval times[2]) { if (times == NULL) { /* The user wants their given fake times left alone but they requested NOW, so turn it into fake NOW */ - fake_gettimeofday(&tn[0]); + if (fake_current_timeval(&tn[0]) == -1) + { + return -1; + } tn[1] = tn[0]; times = tn; } @@ -1364,6 +1374,22 @@ static int fake_current_realtime(struct timespec *tp) return fake_clock_gettime(CLOCK_REALTIME, tp); } +static int fake_current_timeval(struct timeval *tv) +{ + struct timespec ts; + int result; + + result = fake_current_realtime(&ts); + if (result == -1) + { + return -1; + } + + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000; + return 0; +} + /* This conditionally offsets 2 timespec values. The caller's out_times array * always contains valid translated values, even if in_times was NULL. */ static int fake_two_timespec(const struct timespec in_times[2], struct timespec out_times[2]) diff --git a/test/timetest.c b/test/timetest.c index e559b42..96fd054 100644 --- a/test/timetest.c +++ b/test/timetest.c @@ -41,6 +41,7 @@ #include #include #include +#include #define MONO_FIX_TIMEOUT_SECONDS 1 #define MONO_FIX_TOLERANCE_SECONDS 0.25 // Increased tolerance slightly for CI environments @@ -57,6 +58,50 @@ static int fake_monotonic_clock = 0; static int fake_monotonic_clock = 1; #endif +static void test_utime_now(void) +{ + char path[] = "/tmp/libfaketime-utime-XXXXXX"; + int fd; + + fd = mkstemp(path); + if (fd == -1) + { + perror("mkstemp"); + exit(EXIT_FAILURE); + } + + if (utime(path, NULL) == -1) + { + perror("utime(NULL)"); + close(fd); + unlink(path); + exit(EXIT_FAILURE); + } + + if (utimes(path, NULL) == -1) + { + perror("utimes(NULL)"); + close(fd); + unlink(path); + exit(EXIT_FAILURE); + } + + if (close(fd) == -1) + { + perror("close"); + unlink(path); + exit(EXIT_FAILURE); + } + + if (unlink(path) == -1) + { + perror("unlink"); + exit(EXIT_FAILURE); + } + + printf("utime()/utimes(): NOW handling passed\n"); +} + static void test_utimens_now(void) { char path[] = "/tmp/libfaketime-utimensat-XXXXXX"; @@ -369,6 +414,7 @@ printf("%s", 0 == 1 ? argv[0] : ""); printf("gettimeofday() : Current date and time: %s", ctime(&tv.tv_sec)); #ifndef __APPLE__ + test_utime_now(); test_utimens_now(); if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) {