diff options
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | README | 33 | ||||
-rw-r--r-- | src/Makefile | 6 | ||||
-rw-r--r-- | src/Makefile.MacOS | 7 | ||||
-rw-r--r-- | src/faketime.c | 45 |
5 files changed, 92 insertions, 3 deletions
@@ -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. @@ -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; |