diff options
-rw-r--r-- | src/libfaketime.c | 75 | ||||
-rw-r--r-- | src/time_ops.h | 8 |
2 files changed, 79 insertions, 4 deletions
diff --git a/src/libfaketime.c b/src/libfaketime.c index b67bbe4..c3cbdf8 100644 --- a/src/libfaketime.c +++ b/src/libfaketime.c @@ -110,6 +110,13 @@ typedef int clockid_t; #define CLOCK_MONOTONIC_RAW (CLOCK_MONOTONIC + 1) #endif +#ifdef FAKE_FILE_TIMESTAMPS +struct utimbuf { + time_t actime; /* access time */ + time_t modtime; /* modification time */ +}; +#endif + /* * Per thread variable, which we turn on inside real_* calls to avoid modifying * time multiple times of for the whole process to prevent faking time @@ -200,6 +207,11 @@ static int apple_clock_gettime (clockid_t clk_id, struct timespec * static clock_serv_t clock_serv_real; #endif +#ifdef FAKE_FILE_TIMESTAMPS +static int (*real_utimes) (const char *filename, const struct timeval times[2]); +static int (*real_utime) (const char *filename, const struct utimbuf *times); +#endif + static int initialized = 0; /* prototypes */ @@ -1056,6 +1068,65 @@ int __lxstat64 (int ver, const char *path, struct stat64 *buf) } #endif +#ifdef FAKE_FILE_TIMESTAMPS +int utime(const char *filename, const struct utimbuf *times) +{ + if (!initialized) + { + ftpl_init(); + } + if (NULL == real_utime) + { /* dlsym() failed */ +#ifdef DEBUG + (void) fprintf(stderr, "faketime problem: original utime() not found.\n"); +#endif + return -1; /* propagate error to caller */ + } + + int result; + struct utimbuf ntbuf; + ntbuf.actime = times->actime - user_offset.tv_sec; + ntbuf.modtime = times->modtime - user_offset.tv_sec; + DONT_FAKE_TIME(result = real_utime(filename, &ntbuf)); + if (result == -1) + { + return -1; + } + + return result; +} + +int utimes(const char *filename, const struct timeval times[2]) +{ + if (!initialized) + { + ftpl_init(); + } + if (NULL == real_utimes) + { /* dlsym() failed */ +#ifdef DEBUG + (void) fprintf(stderr, "faketime problem: original utimes() not found.\n"); +#endif + return -1; /* propagate error to caller */ + } + + int result; + struct timeval tn[2]; + struct timeval user_offset2; + user_offset2.tv_sec = user_offset.tv_sec; + user_offset2.tv_usec = 0; + timersub(×[0], &user_offset2, &tn[0]); + timersub(×[1], &user_offset2, &tn[1]); + DONT_FAKE_TIME(result = real_utimes(filename, tn)); + if (result == -1) + { + return -1; + } + + return result; +} +#endif + /* * ======================================================================= * Faked system functions: sleep/alarm/poll/timer related === FAKE(SLEEP) @@ -2197,6 +2268,10 @@ static void ftpl_init(void) real_lstat64 = dlsym(RTLD_NEXT, "__lxstat64"); real_time = dlsym(RTLD_NEXT, "time"); real_ftime = dlsym(RTLD_NEXT, "ftime"); +#ifdef FAKE_FILE_TIMESTAMPS + real_utimes = dlsym(RTLD_NEXT, "utimes"); + real_utime = dlsym(RTLD_NEXT, "utime"); +#endif #if defined(__alpha__) && defined(__GLIBC__) real_gettimeofday = dlvsym(RTLD_NEXT, "gettimeofday", "GLIBC_2.1"); #else diff --git a/src/time_ops.h b/src/time_ops.h index 057cd48..9b883a4 100644 --- a/src/time_ops.h +++ b/src/time_ops.h @@ -60,9 +60,9 @@ #define timermul2(tvp, c, result, prefix) \ do \ { \ - long long tmp_time; \ - tmp_time = (c) * ((tvp)->tv_sec * SEC_TO_##prefix##SEC + \ - (tvp)->tv_##prefix##sec); \ + int64_t tmp_time; \ + tmp_time = (c) * (int64_t) ((tvp)->tv_sec * SEC_TO_##prefix##SEC + \ + (int64_t) (tvp)->tv_##prefix##sec); \ (result)->tv_##prefix##sec = tmp_time % SEC_TO_##prefix##SEC; \ (result)->tv_sec = (tmp_time - (result)->tv_##prefix##sec) / \ SEC_TO_##prefix##SEC; \ @@ -89,7 +89,7 @@ #ifndef timersub #define timersub(a, b, result) timersub2(a, b, result, u) #endif -#ifndef timersub +#ifndef timermul #define timermul(a, c, result) timermul2(a, c, result, u) #endif |