diff options
author | Wolfgang Hommel <wolfgang.hommel@unibw.de> | 2019-12-14 21:49:23 +0100 |
---|---|---|
committer | Wolfgang Hommel <wolfgang.hommel@unibw.de> | 2019-12-14 21:49:23 +0100 |
commit | 78385ba8b7a12c1eb876dbcf516aa5cca2cca5ab (patch) | |
tree | 3ae8c31ce429bae5f96e973b6cb2b9b837157351 | |
parent | b3dcef470e8e6d467057f83821c7792ee36f4455 (diff) | |
download | libfaketime-78385ba8b7a12c1eb876dbcf516aa5cca2cca5ab.tar.gz |
Use -DFAKE_FILE_TIMESTAMPS to intercept utime[s](), by @speq, #183
-rw-r--r-- | src/libfaketime.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/libfaketime.c b/src/libfaketime.c index 745384d..616e0c4 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 */ @@ -1032,6 +1044,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) @@ -2173,6 +2244,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 |