summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Hommel <wolfgang.hommel@unibw.de>2019-12-14 21:49:23 +0100
committerWolfgang Hommel <wolfgang.hommel@unibw.de>2019-12-14 21:49:23 +0100
commit78385ba8b7a12c1eb876dbcf516aa5cca2cca5ab (patch)
tree3ae8c31ce429bae5f96e973b6cb2b9b837157351
parentb3dcef470e8e6d467057f83821c7792ee36f4455 (diff)
downloadlibfaketime-78385ba8b7a12c1eb876dbcf516aa5cca2cca5ab.tar.gz
Use -DFAKE_FILE_TIMESTAMPS to intercept utime[s](), by @speq, #183
-rw-r--r--src/libfaketime.c75
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(&times[0], &user_offset2, &tn[0]);
+ timersub(&times[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