mirror of
https://github.com/wolfcw/libfaketime.git
synced 2026-05-17 08:36:28 +03:00
Add --exclude-monotonic command line option.
--exclude-monotonic prevents faketime from overriding the clock with id CLOCK_MONOTONIC when using clock_gettime. Add DONT_FAKE_MONOTONIC env variable to libfaketime that has the same effect. Add functional test for DONT_FAKE_MONOTONIC support.
This commit is contained in:
committed by
Julien Gilli
parent
3bed636a41
commit
d19da98bb4
@@ -72,8 +72,9 @@ void usage(const char *name)
|
||||
printf("for advanced options, such as stopping the wall clock and make it run faster or slower.\n");
|
||||
printf("\n");
|
||||
printf("The optional switches are:\n");
|
||||
printf(" -m : Use the multi-threaded version of libfaketime\n");
|
||||
printf(" -f : Use the advanced timestamp specification format (see manpage)\n");
|
||||
printf(" -m : Use the multi-threaded version of libfaketime\n");
|
||||
printf(" -f : Use the advanced timestamp specification format (see manpage)\n");
|
||||
printf(" --exclude-monotonic : Prevent monotonic clock from drifting (not the raw monotonic one)\n");
|
||||
printf("\n");
|
||||
printf("Examples:\n");
|
||||
printf("%s 'last friday 5 pm' /bin/date\n", name);
|
||||
@@ -122,6 +123,12 @@ int main (int argc, char **argv)
|
||||
curr_opt++;
|
||||
continue;
|
||||
}
|
||||
else if (0 == strcmp(argv[curr_opt], "--exclude-monotonic"))
|
||||
{
|
||||
setenv("DONT_FAKE_MONOTONIC", "1", true);
|
||||
curr_opt++;
|
||||
continue;
|
||||
}
|
||||
else if ((0 == strcmp(argv[curr_opt], "-v")) ||
|
||||
(0 == strcmp(argv[curr_opt], "--version")))
|
||||
{
|
||||
|
||||
@@ -199,6 +199,8 @@ static char ft_spawn_target[1024];
|
||||
static long ft_spawn_secs = -1;
|
||||
static long ft_spawn_ncalls = -1;
|
||||
|
||||
static int fake_monotonic_clock = 1;
|
||||
|
||||
/*
|
||||
* Static timespec to store our startup time, followed by a load-time library
|
||||
* initialization declaration.
|
||||
@@ -237,6 +239,7 @@ static void ft_shm_init (void)
|
||||
{
|
||||
int ticks_shm_fd;
|
||||
char sem_name[256], shm_name[256], *ft_shared_env = getenv("FAKETIME_SHARED");
|
||||
|
||||
if (ft_shared_env != NULL)
|
||||
{
|
||||
if (sscanf(ft_shared_env, "%255s %255s", sem_name, shm_name) < 2)
|
||||
@@ -1290,7 +1293,10 @@ int clock_gettime(clockid_t clk_id, struct timespec *tp)
|
||||
if (result == -1) return result; /* original function failed */
|
||||
|
||||
/* pass the real current time to our faking version, overwriting it */
|
||||
result = fake_clock_gettime(clk_id, tp);
|
||||
if (fake_monotonic_clock || clk_id != CLOCK_MONOTONIC)
|
||||
{
|
||||
result = fake_clock_gettime(clk_id, tp);
|
||||
}
|
||||
|
||||
/* return the result to the caller */
|
||||
return result;
|
||||
@@ -1454,6 +1460,13 @@ void __attribute__ ((constructor)) ftpl_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((tmp_env = getenv("DONT_FAKE_MONOTONIC")) != NULL)
|
||||
{
|
||||
if (0 == strcmp(tmp_env, "1"))
|
||||
{
|
||||
fake_monotonic_clock = 0;
|
||||
}
|
||||
}
|
||||
/* Check whether we actually should be faking the returned timestamp. */
|
||||
|
||||
/* We can prevent faking time for specified commands */
|
||||
@@ -2010,7 +2023,10 @@ int __clock_gettime(clockid_t clk_id, struct timespec *tp)
|
||||
if (result == -1) return result; /* original function failed */
|
||||
|
||||
/* pass the real current time to our faking version, overwriting it */
|
||||
result = fake_clock_gettime(clk_id, tp);
|
||||
if (fake_monotonic_clock || clk_id != CLOCK_MONOTONIC)
|
||||
{
|
||||
result = fake_clock_gettime(clk_id, tp);
|
||||
}
|
||||
|
||||
/* return the result to the caller */
|
||||
return result;
|
||||
|
||||
87
test/functests/test_exclude_mono.sh
Normal file
87
test/functests/test_exclude_mono.sh
Normal file
@@ -0,0 +1,87 @@
|
||||
# Checks that setting DONT_FAKE_MONOTONIC actually prevent
|
||||
# libfaketime from faking monotonic clocks.
|
||||
#
|
||||
# We do this by freezing time at a specific and arbitrary date with faketime,
|
||||
# and making sure that if we set DONT_FAKE_MONOTONIC to 1, calling
|
||||
# clock_gettime(CLOCK_MONOTONIC) returns two different values.
|
||||
#
|
||||
# We also make sure that if we don't set DONT_FAKE_MONOTONIC to 1, in other
|
||||
# words when we use the default behavior, two subsequent calls to
|
||||
# clock_gettime(CLOCK_MONOTONIC) do return different values.
|
||||
|
||||
init()
|
||||
{
|
||||
typeset testsuite="$1"
|
||||
PLATFORM=$(platform)
|
||||
if [ -z "$PLATFORM" ]; then
|
||||
echo "$testsuite: unknown platform! quitting"
|
||||
return 1
|
||||
fi
|
||||
echo "# PLATFORM=$PLATFORM"
|
||||
return 0
|
||||
}
|
||||
|
||||
run()
|
||||
{
|
||||
init
|
||||
|
||||
run_testcase dont_fake_mono
|
||||
run_testcase fake_mono
|
||||
}
|
||||
|
||||
get_token()
|
||||
{
|
||||
string=$1
|
||||
token_index=$2
|
||||
separator=$3
|
||||
|
||||
echo $string | cut -d "$separator" -f $token_index
|
||||
}
|
||||
|
||||
assert_timestamps_neq()
|
||||
{
|
||||
timestamps=$1
|
||||
msg=$2
|
||||
|
||||
first_timestamp=$(get_token "${timestamps}" 1 ' ')
|
||||
second_timestamp=$(get_token "${timestamps}" 2 ' ')
|
||||
|
||||
assertneq "${first_timestamp}" "${second_timestamp}" "${msg}"
|
||||
}
|
||||
|
||||
assert_timestamps_eq()
|
||||
{
|
||||
timestamps=$1
|
||||
msg=$2
|
||||
|
||||
first_timestamp=$(get_token "${timestamps}" 1 ' ')
|
||||
second_timestamp=$(get_token "${timestamps}" 2 ' ')
|
||||
|
||||
asserteq "${first_timestamp}" "${second_timestamp}" "${msg}"
|
||||
}
|
||||
|
||||
get_monotonic_time()
|
||||
{
|
||||
dont_fake_mono=$1; shift;
|
||||
clock_id=$1; shift;
|
||||
DONT_FAKE_MONOTONIC=${dont_fake_mono} fakecmd "2014-07-21 09:00:00" \
|
||||
/bin/bash -c "for i in 1 2; do \
|
||||
perl -w -MTime::HiRes=clock_gettime,${clock_id} -E \
|
||||
'say clock_gettime(${clock_id})'; \
|
||||
sleep 1; \
|
||||
done"
|
||||
}
|
||||
|
||||
dont_fake_mono()
|
||||
{
|
||||
timestamps=$(get_monotonic_time 1 CLOCK_MONOTONIC)
|
||||
msg="When not faking monotonic time, timestamps should be different"
|
||||
assert_timestamps_neq "${timestamps}" "${msg}"
|
||||
}
|
||||
|
||||
fake_mono()
|
||||
{
|
||||
timestamps=$(get_monotonic_time 0 CLOCK_MONOTONIC)
|
||||
msg="When faking monotonic, timestamps should be equal"
|
||||
assert_timestamps_eq "${timestamps}" "${msg}"
|
||||
}
|
||||
Reference in New Issue
Block a user