summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--README33
-rw-r--r--src/Makefile6
-rw-r--r--src/Makefile.MacOS7
-rw-r--r--src/faketime.c45
5 files changed, 92 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index e849385..0c1e6a0 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,10 @@ Since 0.8.2:
it will be sent two years into the future. Those limiting
start and stop times can be specified in seconds or as the
number of any time-related function calls within the program.
+ - Added a feature to spawn an external process after x seconds
+ or y time-related system calls. This can, for example, be used
+ to execute an arbitrary shell script x seconds after a program
+ has been started.
Since 0.8.1:
- Added a MacOS port.
diff --git a/README b/README
index 0b32cf6..b156131 100644
--- a/README
+++ b/README
@@ -18,6 +18,7 @@ Content of this file:
f) Faking the date and time system-wide
g) Using the "faketime" wrapper script
h) "Limiting" libfaketime
+ i) Spawning an external process
5. License
6. Contact
@@ -384,6 +385,38 @@ functionality unless you are sure you really need it and know what you are
doing.
+4i) Spawning an external process
+--------------------------------
+
+From version 0.9 on, libfaketime can execute a shell command once after an
+arbitrary number of seconds or number of time-related system calls of the
+program started. This has two limitations one needs to be aware of:
+
+* Spawning the external process happens during a time-related system call
+ of the original program. If you want the external process to be started
+ 5 seconds after program start, but this program does not make any time-
+ related system calls before run-time second 8, the start of your external
+ process will be delayed until run-time second 8.
+
+* The original program is blocked until the external process is finished,
+ because the intercepting time-related system call will not return earlier. If
+ you need to start a long-running external process, make sure it forks into the
+ background.
+
+Spawning the external process is controlled using three environment variables:
+FAKETIME_SPAWN_TARGET, FAKETIME_SPAWN_SECONDS, FAKETIME_SPAWN_NUMCALLS.
+
+Example (using bash on Linux):
+
+(... usual libfaketime setup here, setting LD_PRELOAD and FAKETIME ...)
+export FAKETIME_SPAWN_TARGET="/bin/echo 'Hello world'"
+export FAKETIME_SPAWN_SECONDS=5
+/opt/local/bin/myprogram
+
+This will run the "echo" command with the given parameter during the first
+time-related system function call that "myprogram" performs after running for 5
+seconds.
+
5. License
----------
diff --git a/src/Makefile b/src/Makefile
index 32ab293..9118815 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -34,6 +34,10 @@
# - Support environment variables that limit time faking to certain
# time intervals or number of function calls.
#
+# SPAWNSUPPORT
+# - Enable support for spawning an external process at a given
+# timestamp.
+#
# * Compilation addition: second libMT target added for building the pthread-
# enabled library as a separate library
#
@@ -48,7 +52,7 @@ INSTALL = install
PREFIX = /usr/local
-CFLAGS += -std=gnu99 -Wall -DFAKE_STAT -DFAKE_INTERNAL_CALLS -fPIC -DPOSIX_REALTIME -DLIMITEDFAKING
+CFLAGS += -std=gnu99 -Wall -DFAKE_STAT -DFAKE_INTERNAL_CALLS -fPIC -DPOSIX_REALTIME -DLIMITEDFAKING -DSPAWNSUPPORT
LDFLAGS += -shared -ldl -lm -lpthread
SRC = faketime.c
diff --git a/src/Makefile.MacOS b/src/Makefile.MacOS
index f15ea74..38d98c2 100644
--- a/src/Makefile.MacOS
+++ b/src/Makefile.MacOS
@@ -34,6 +34,10 @@
# - Support environment variables that limit time faking to certain
# time intervals or number of function calls.
#
+# SPAWNSUPPORT
+# - Enable support for spawning an external process at a given
+# timestamp.
+#
#
# * Compilation addition: second libMT target added for building the pthread-
# enabled library as a separate library
@@ -55,8 +59,7 @@ PREFIX = /usr/local
# 10.5
#CFLAGS = -dynamiclib -DFAKE_INTERNAL_CALLS -arch i386 -arch ppc
# 10.6
-CFLAGS = -dynamiclib -DFAKE_INTERNAL_CALLS -arch i386 -arch x86_64 -DLIMITEDFAKING
-
+CFLAGS = -dynamiclib -DFAKE_INTERNAL_CALLS -arch i386 -arch x86_64 -DLIMITEDFAKING -DSPAWNSUPPORT
SRC = faketime.c
SONAME = 1
diff --git a/src/faketime.c b/src/faketime.c
index 1745380..a20a2ff 100644
--- a/src/faketime.c
+++ b/src/faketime.c
@@ -640,6 +640,16 @@ time_t fake_time(time_t *time_tptr) {
static long FAKETIME_STOP_AFTER_NUMCALLS = -1;
#endif
+#ifdef SPAWNSUPPORT
+ static int spawned = 0;
+ static long spawn_callcounter = 0;
+ static int spawn_initialized = 0;
+ char spawn_envvarbuf[32];
+ static char FAKETIME_SPAWN_TARGET[1024];
+ static long FAKETIME_SPAWN_SECONDS = -1;
+ static long FAKETIME_SPAWN_NUMCALLS = -1;
+#endif
+
/*
* This no longer appears to be necessary in Mac OS X 10.7 Lion
*/
@@ -692,6 +702,41 @@ static pthread_mutex_t time_mutex=PTHREAD_MUTEX_INITIALIZER;
}
#endif
+#ifdef SPAWNSUPPORT
+ /* check whether we should spawn an external command */
+
+ if (ftpl_starttime > 0) {
+
+ if(spawn_initialized == 0) {
+ if (getenv("FAKETIME_SPAWN_TARGET") != NULL) {
+ (void) strncpy(FAKETIME_SPAWN_TARGET, getenv("FAKETIME_SPAWN_TARGET"), 1024);
+
+ if (getenv("FAKETIME_SPAWN_SECONDS") != NULL) {
+ (void) strncpy(spawn_envvarbuf, getenv("FAKETIME_SPAWN_SECONDS"), 30);
+ FAKETIME_SPAWN_SECONDS = atol(spawn_envvarbuf);
+ }
+
+ if (getenv("FAKETIME_SPAWN_NUMCALLS") != NULL) {
+ (void) strncpy(spawn_envvarbuf, getenv("FAKETIME_SPAWN_NUMCALLS"), 30);
+ FAKETIME_SPAWN_NUMCALLS = atol(spawn_envvarbuf);
+ }
+ }
+ spawn_initialized = 1;
+ }
+
+ if (spawned == 0) { /* exec external command once only */
+ if ((spawn_callcounter + 1) >= spawn_callcounter) spawn_callcounter++;
+ if ((((*time_tptr - ftpl_starttime) == FAKETIME_SPAWN_SECONDS) || (spawn_callcounter == FAKETIME_SPAWN_NUMCALLS)) && (spawned == 0)) {
+ spawned = 1;
+ system(FAKETIME_SPAWN_TARGET);
+ }
+
+ }
+
+ }
+#endif
+
+
if (last_data_fetch > 0) {
if ((*time_tptr - last_data_fetch) > cache_duration) {
cache_expired = 1;