summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Hommel <wolfgang.hommel@unibw.de>2019-08-20 19:43:15 +0200
committerWolfgang Hommel <wolfgang.hommel@unibw.de>2019-08-20 19:43:15 +0200
commit57917c4d5a4c64f3db6424c266c33e7a5314b092 (patch)
tree4279a42d2c3b8247f28a8a8e28d9a60f8e493d05
parente85863f671cfe7ae6e48eae4696b4946e5cf632e (diff)
downloadlibfaketime-57917c4d5a4c64f3db6424c266c33e7a5314b092.tar.gz
Added follow-file-timestamp mode via FAKETIME='%' and FAKETIME_FOLLOW_FILE (#156)
-rw-r--r--README40
-rw-r--r--src/libfaketime.c28
2 files changed, 68 insertions, 0 deletions
diff --git a/README b/README
index 664f1a4..8d52e90 100644
--- a/README
+++ b/README
@@ -205,6 +205,22 @@ specified absolute time. The 'start at' format allows a 'relative' clock
operation as described below in section 4d), but using a 'start at' time
instead of an offset time.
+If the started process itself starts other (child) processes, they by default
+will start with the specified start-at-date again. If this is not what you need,
+set the environment variable FAKETIME_DONT_RESET=1. Try these examples to see
+the difference:
+
+LD_PRELOAD=src/libfaketime.so.1 FAKETIME="@2000-01-01 11:12:13" \
+ FAKETIME_DONT_RESET=1 \
+ /bin/bash -c 'while [ $SECONDS -lt 5 ]; do date; sleep 1; done'
+
+LD_PRELOAD=src/libfaketime.so.1 FAKETIME="@2000-01-01 11:12:13" \
+ /bin/bash -c 'while [ $SECONDS -lt 5 ]; do date; sleep 1; done'
+
+In the second example, the "date" command will always print the same time,
+while in the first example, with FAKETIME_DONT_RESET set, time will increment
+even though all the "date" commands are new processes.
+
4d) Using offsets for relative dates
------------------------------------
@@ -336,6 +352,30 @@ with FAKETIME_NO_CACHE=1. Remember that disabling the cache may negatively
influence the performance.
+Setting FAKETIME by means of a file timestamp
+---------------------------------------------
+
+Based on a proposal by Hitoshi Harada (umitanuki), the "start at" time can now be
+set through any file in the file system by setting the FAKETIME environment variable
+to "%" (a percent sign) and FAKETIME_FOLLOW_FILE to the name of the file whose
+modification timestamp shall be used as source for the "start at" time.
+
+Usage example:
+
+# create any file with December 24th, 2009, 12:34:56 as timestamp
+touch -t 0912241234.56 /tmp/my-demo-file.tmp
+
+# run a bash shell with an endless loop printing the current time
+LD_PRELOAD=/path/to/libfaketime.so.1 \
+ FAKETIME='%' FAKETIME_FOLLOW_FILE=/tmp/my-demo-file.tmp \
+ FAKETIME_DONT_RESET=1 \
+ bash -c 'while true ; do date ; sleep 1 ; done'
+
+# now, while the above is running, change the file's timestamp
+# (in a different terminal window or whatever)
+touch -t 2002290123.45 /tmp/my-demo-file.tmp
+
+
4f) Faking the date and time system-wide
----------------------------------------
diff --git a/src/libfaketime.c b/src/libfaketime.c
index 59ffd7f..f5a4ea2 100644
--- a/src/libfaketime.c
+++ b/src/libfaketime.c
@@ -1794,6 +1794,34 @@ static void parse_ft_string(const char *user_faked_time)
goto parse_modifiers;
break;
+ case '%': /* follow file timestamp as suggested by Hitoshi Harada (umitanuki) */
+ ft_mode = FT_START_AT;
+ struct stat master_file_stats;
+ int ret;
+ if (NULL == getenv("FAKETIME_FOLLOW_FILE"))
+ {
+ fprintf(stderr, "libfaketime: %% operator in FAKETIME setting requires environment variable FAKETIME_FOLLOW_FILE set.\n");
+ exit(1);
+ }
+ else
+ {
+ DONT_FAKE_TIME(ret = stat(getenv("FAKETIME_FOLLOW_FILE"), &master_file_stats));
+ if (ret == -1)
+ {
+ fprintf(stderr, "libfaketime: Cannot get timestamp of file %s as requested by %% operator.\n", getenv("FAKETIME_FOLLOW_FILE"));
+ exit(1);
+ }
+ else
+ {
+ user_faked_time_timespec.tv_sec = master_file_stats.st_mtime;
+ user_faked_time_timespec.tv_nsec = 0;
+ }
+ }
+ if (NULL == getenv("FAKETIME_DONT_RESET"))
+ system_time_from_system(&ftpl_starttime);
+ goto parse_modifiers;
+ break;
+
case 'i':
case 'x': /* Only modifiers are passed, don't fall back to strptime */
parse_modifiers: