mirror of
https://github.com/wolfcw/libfaketime.git
synced 2026-05-19 09:46:11 +03:00
Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c0b101a84 | ||
|
|
44a6d1f0fa | ||
|
|
772d9523a7 | ||
|
|
8b5519d496 | ||
|
|
3ba66842aa | ||
|
|
4359458c7c | ||
|
|
726c4657fc | ||
|
|
8853afb509 | ||
|
|
48f280ac86 | ||
|
|
47e6f5f33d | ||
|
|
e4e5ea6211 | ||
|
|
206ae9ea80 | ||
|
|
cce377b371 | ||
|
|
5e6ed4cd2c | ||
|
|
55e634a6ca | ||
|
|
532816864e | ||
|
|
4564afb924 | ||
|
|
5b8673df54 | ||
|
|
e00ba47ca9 | ||
|
|
ca2f3fefa1 | ||
|
|
dacc5866a7 | ||
|
|
b35e7c8ca6 | ||
|
|
25a60d0292 | ||
|
|
d90c8c26d3 | ||
|
|
c683c81417 | ||
|
|
f19d68ea32 | ||
|
|
c36674c27f | ||
|
|
112809f986 | ||
|
|
9498b2cacc | ||
|
|
c9a3b1bace | ||
|
|
834953480e | ||
|
|
c1d10321a7 | ||
|
|
58ccfb6c27 | ||
|
|
1e25e1f042 | ||
|
|
690ed3f158 | ||
|
|
d2f0daf092 | ||
|
|
c5b5d0b56e |
8
.github/workflows/make-test.yml
vendored
8
.github/workflows/make-test.yml
vendored
@@ -2,22 +2,22 @@ name: Run make test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
schedule:
|
||||
- cron: '30 9 * * *'
|
||||
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macOS-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: make
|
||||
run: make
|
||||
run: FAKETIME_COMPILE_CFLAGS="-DFORCE_MONOTONIC_FIX" make
|
||||
- name: make test
|
||||
run: make test
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,6 +1,7 @@
|
||||
*.o
|
||||
*.so.1
|
||||
timetest
|
||||
test/getrandom_test
|
||||
|
||||
src/libfaketime.dylib.1
|
||||
src/libfaketime.1.dylib
|
||||
|
||||
10
.travis.yml
10
.travis.yml
@@ -3,11 +3,19 @@ language: c
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
arch: amd64
|
||||
compiler: gcc
|
||||
- os: linux
|
||||
arch: ppc64le
|
||||
compiler: gcc
|
||||
- os: osx
|
||||
osx_image: xcode11
|
||||
|
||||
script:
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
- FAKETIME_COMPILE_CFLAGS="-DFORCE_MONOTONIC_FIX" make
|
||||
- if [ "$TRAVIS_ARCH" = ppc64le ]; then
|
||||
FAKETIME_COMPILE_CFLAGS="-DFORCE_MONOTONIC_FIX -DFORCE_PTHREAD_NONVER" make;
|
||||
else
|
||||
FAKETIME_COMPILE_CFLAGS="-DFORCE_MONOTONIC_FIX" make;
|
||||
fi
|
||||
- make test
|
||||
|
||||
19
NEWS
19
NEWS
@@ -1,8 +1,23 @@
|
||||
Since 0.9.8:
|
||||
- When compiled with the CFLAG FAKE_RANDOM set,
|
||||
libfaketime will intercept calls to getrandom()
|
||||
and return pseudorandom numbers for determinism.
|
||||
The mechanism needs to be activated by setting
|
||||
the environment variable FAKERANDOM_SEED to a
|
||||
64-bit seed value, e.g., "0x12345678DEADBEEF".
|
||||
Please note that this completely breaks the
|
||||
security of random numbers for cryptographic
|
||||
purposes and should only be used for deterministic
|
||||
tests. Never use this in production!
|
||||
- When the environment variable FAKETIME_TIMESTAMP_FILE is
|
||||
set, points to a writeable (creatable) custom config file
|
||||
and the environment variable FAKETIME_UPDATE_TIMESTAMP_FILE
|
||||
is "1", then the file also is updated on each call. By
|
||||
this, a common "virtual time" can be shared by several
|
||||
processes, where each can adjust the time for all.
|
||||
- Additional link-time LDFLAGS can be passed via the
|
||||
environment variable FAKETIME_LINK_FLAGS when
|
||||
running 'make'.
|
||||
|
||||
Since 0.9.8:
|
||||
- Compile-time CFLAG FAKE_SETTIME can be enabled to
|
||||
intercept calls to clock_settime(), settimeofday(), and
|
||||
adjtime(). (suggested and prototyped by @ojura)
|
||||
|
||||
116
README
116
README
@@ -1,5 +1,5 @@
|
||||
libfaketime, version 0.9.8 (August 2019)
|
||||
========================================
|
||||
libfaketime, version 0.9.9 (February 2021)
|
||||
==========================================
|
||||
|
||||
|
||||
Content of this file:
|
||||
@@ -20,6 +20,7 @@ Content of this file:
|
||||
i) "Limiting" libfaketime per process
|
||||
j) Spawning an external process
|
||||
k) Saving timestamps to file, loading them from file
|
||||
l) Replacing random numbers with deterministic number sequences
|
||||
5. License
|
||||
6. Contact
|
||||
|
||||
@@ -187,19 +188,21 @@ linker configuration file, e.g., /etc/ld.so.conf.d/local.conf, and then run
|
||||
the "ldconfig" command. Afterwards, using LD_PRELOAD=libfaketime.so.1 suffices.
|
||||
|
||||
However, also the faked time should be specified; otherwise, libfaketime will
|
||||
be loaded, but just report the real system time. There are three ways to
|
||||
be loaded, but just report the real system time. There are multiple ways to
|
||||
specify the faked time:
|
||||
|
||||
a) By setting the environment variable FAKETIME.
|
||||
b) By using the file given in the environment variable FAKETIME_TIMESTAMP_FILE
|
||||
c) By using the file .faketimerc in your home directory.
|
||||
d) By using the file /etc/faketimerc for a system-wide default.
|
||||
e) By using FAKETIME_UPDATE_TIMESTAMP_FILE and date -s "<time>" or alike.
|
||||
|
||||
If you want to use b) c) or d), $HOME/.faketimerc or /etc/faketimerc consist of
|
||||
only one line of text with exactly the same content as the FAKETIME environment
|
||||
variable, which is described below. Note that /etc/faketimerc will only be used
|
||||
if there is no $HOME/.faketimerc and no FAKETIME_TIMESTAMP_FILE file exists.
|
||||
Also, the FAKETIME environment variable _always_ has priority over the files.
|
||||
For FAKETIME_UPDATE_TIMESTAMP_FILE please see below.
|
||||
|
||||
|
||||
4b) Using absolute dates
|
||||
@@ -324,7 +327,7 @@ the same global clock without restarting it at the start of each process.
|
||||
Please note that using "x" or "i" in FAKETIME still requires giving an offset
|
||||
(see section 4d). This means that "+1y x2" will work, but "x2" only will not.
|
||||
If you do not want to fake the time, but just modify clock speed, use something
|
||||
like "+0 x2", i.e., use an explizit zero offset as a prefix in your FAKETIME.
|
||||
like "+0 x2", i.e., use an explicit zero offset as a prefix in your FAKETIME.
|
||||
|
||||
For testing, your should run a command like
|
||||
|
||||
@@ -368,7 +371,8 @@ may take up to 10 seconds before the new fake time is applied. If this is a
|
||||
problem in your scenario, you can change number of seconds before the file is read
|
||||
again with environment variable FAKETIME_CACHE_DURATION, or disable caching at all
|
||||
with FAKETIME_NO_CACHE=1. Remember that disabling the cache may negatively
|
||||
influence the performance.
|
||||
influence the performance (especially when not using FAKETIME environment
|
||||
but configuration files, such as FAKETIME_TIMESTAMP_FILE).
|
||||
|
||||
|
||||
Setting FAKETIME by means of a file timestamp
|
||||
@@ -434,9 +438,14 @@ Cleaning up shared memory
|
||||
-------------------------
|
||||
|
||||
libfaketime uses semaphores and shared memory on platforms that support it in
|
||||
order to sync faketime settings across parent-child processes. It will clean
|
||||
up when it exits properly. However, when processes are terminated (e.g., by
|
||||
Ctrl-C on command line), shared memory cannot be cleaned up properly. In such
|
||||
order to sync faketime settings across parent-child processes.
|
||||
|
||||
Please note that this does not share the time set by settimeofday (for that
|
||||
see FAKETIME_UPDATE_TIMESTAMP_FILE below).
|
||||
|
||||
libfaketime will clean up when it exits properly.
|
||||
However, when processes are terminated (e.g., by Ctrl-C on command line),
|
||||
shared memory cannot be cleaned up properly. In such
|
||||
cases, you should occasionally delete
|
||||
|
||||
/dev/shm/faketime_shm_* and
|
||||
@@ -461,9 +470,54 @@ Intercepting time-setting calls
|
||||
|
||||
libfaketime can be compiled with the CFLAG "-DFAKE_SETTIME" in order
|
||||
to also intercept time-setting functions, i.e., clock_settime(),
|
||||
settimeofday(), and adjtime(). Instead of passing the timestamp a
|
||||
program sets through to the system, only the FAKETIME environment
|
||||
variable will be adjusted accordingly.
|
||||
settimeofday(), and adjtime(). The FAKETIME environment
|
||||
variable will be adjusted on each call.
|
||||
|
||||
When the environment variable FAKETIME_TIMESTAMP_FILE is set, points to a
|
||||
writeable (creatable) custom config file and the environment variable
|
||||
FAKETIME_UPDATE_TIMESTAMP_FILE is "1", then the file also is updated on each
|
||||
call. By this, a common "virtual time" can be shared by several
|
||||
processes, where each can adjust the time for all.
|
||||
|
||||
|
||||
Sharing "virtual settable time" between independent processes
|
||||
-------------------------------------------------------------
|
||||
|
||||
When libfaketime was compiled with FAKETIME_COMPILE_CFLAGS="-DFAKE_SETTIME",
|
||||
it can be configured to support a common time offset for multiple processes.
|
||||
This for example allows to use "ntpdate" as normal user without affecting
|
||||
system clock, interactively testing software with different dates or testing
|
||||
complex software with multiple independent processes that themself use
|
||||
settime internally.
|
||||
|
||||
Examples:
|
||||
|
||||
$ export LD_PRELOAD=libfaketime.so.1
|
||||
$ export FAKETIME_TIMESTAMP_FILE="/tmp/my-faketime.rc"
|
||||
$ export FAKETIME_UPDATE_TIMESTAMP_FILE=1
|
||||
$ export FAKETIME_CACHE_DURATION=1 # in seconds
|
||||
# or: export FAKETIME_NO_CACHE=1
|
||||
|
||||
$ date -s "1999-12-24 16:00:00"
|
||||
Fri Dec 24 16:00:00 CET 1999
|
||||
$ LD_PRELOAD="" date
|
||||
Thu Apr 9 15:19:38 CEST 2020
|
||||
$ date
|
||||
Fri Dec 24 16:00:02 CET 1999
|
||||
$ /usr/sbin/ntpdate -u clock.isc.org
|
||||
9 Apr 15:18:37 ntpdate[718]: step time server xx offset 640390517.057257 sec
|
||||
$ date
|
||||
Thu Apr 9 15:18:40 CEST 2020
|
||||
|
||||
In another terminal, script or environmment the same variables could be set
|
||||
and the same time would be printed.
|
||||
This also avoid the need to directly update the rc config file to use
|
||||
different times, but of course only supports time offsets.
|
||||
|
||||
Please note that this feature is not compatible with several other features,
|
||||
such as FAKETIME_FOLLOW_FILE, FAKETIME_XRESET and maybe others. After first
|
||||
settime, offsets will be used in FAKETIME_TIMESTAMP_FILE, even if it
|
||||
initially used advanced time specification options.
|
||||
|
||||
|
||||
4f) Faking the date and time system-wide
|
||||
@@ -639,6 +693,11 @@ seconds.
|
||||
4k) Saving timestamps to file, loading them from file
|
||||
-----------------------------------------------------
|
||||
|
||||
To store and load timestamp _offsets_ using _one and the same_ file allowing
|
||||
to share a common "virtual time" between independent processes, please see
|
||||
FAKETIME_UPDATE_TIMESTAMP_FILE above. The FAKETIME_SAVE_FILE feature is
|
||||
different.
|
||||
|
||||
faketime can save faked timestamps to a file specified by FAKETIME_SAVE_FILE
|
||||
environment variable. It can also use the file specified by FAKETIME_LOAD_FILE
|
||||
to replay timestamps from it. After consuming the whole file, libfaketime
|
||||
@@ -658,6 +717,41 @@ faketime needs to be run using the faketime wrapper to use these files. This
|
||||
functionality has been added by Balint Reczey in v0.9.5.
|
||||
|
||||
|
||||
4l) Replacing random numbers with deterministic number sequences
|
||||
----------------------------------------------------------------
|
||||
|
||||
libfaketime can be compiled with the CFLAG FAKE_RANDOM set (see src/Makefile).
|
||||
|
||||
When compiled this way, libfaketime additionally intercepts calls to the
|
||||
function getrandom(), which currently is Linux-specific.
|
||||
|
||||
This functionality is intended to feed a sequence of deterministic, repeatable
|
||||
numbers to applications, which use getrandom(), instead of the random numbers
|
||||
provided by /dev/[u]random.
|
||||
|
||||
For creating the deterministic number sequence, libfaketime internally
|
||||
uses Bernard Widynski's Middle Square Weyl Sequence Random Number Generator,
|
||||
see https://mswsrng.wixsite.com/rand.
|
||||
|
||||
It requires a 64-bit seed value, which has to be passed via the environment
|
||||
variable FAKERANDOM_SEED, as in, for example
|
||||
|
||||
LD_PRELOAD=src/libfaketime.so.1 \
|
||||
FAKERANDOM_SEED="0x12345678DEADBEEF" \
|
||||
test/getrandom_test
|
||||
|
||||
Whenever the same seed value is used, the same sequence of "random-looking"
|
||||
numbers is generated.
|
||||
|
||||
Please be aware that this definitely breaks any security properties that
|
||||
may be attributed to random numbers delivered by getrandom(), e.g., in the
|
||||
context of cryptographic operations. Use it for deterministic testing
|
||||
purposes only. Never use it in production.
|
||||
|
||||
For a discussion on why this apparently not date-/time-related function
|
||||
has been added to libfaketime and how it may evolve, see Github issue #275.
|
||||
|
||||
|
||||
5. License
|
||||
----------
|
||||
|
||||
|
||||
16
README.OSX
16
README.OSX
@@ -1,10 +1,17 @@
|
||||
README file for libfaketime on macOS
|
||||
====================================
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! If you compiled libfaketime successfully but even the simple examples !
|
||||
! with the "date" command do not seem to work, please see the notes about !
|
||||
! SIP (system integrity protection) in this document! !
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
|
||||
Support for macOS has meanwhile matured and many command line and
|
||||
GUI applications will run stable.
|
||||
|
||||
Developments and tests are done on Mojave currently.
|
||||
Developments and tests are done on Catalina currently.
|
||||
|
||||
Version 0.9.5 and higher no longer work with OSX <= 10.6 due to
|
||||
changes in the underlying system libraries. If you need libfaketime
|
||||
@@ -138,6 +145,13 @@ However, there are two important aspects:
|
||||
application to a non-SIP-protected path, and if libfaketime still does not
|
||||
work, feel free to report it.
|
||||
|
||||
Please note that this also applies to simple programs such as /bin/date,
|
||||
which is used as an example in the libfaketime documentation and help texts.
|
||||
|
||||
Again, either disable SIP on your system (which might not be the best idea),
|
||||
or copy the applications / programs you want to use with libfaketime to
|
||||
a different path, which is not SIP-protected, e.g., within your home directory.
|
||||
|
||||
- We cannot and will not help with using libfaketime for proprietary or
|
||||
commercial software unless you are its developer trying to integrate
|
||||
libfaketime. Please contact the developers or the vendor directly if
|
||||
|
||||
@@ -14,6 +14,10 @@ src/Makefile, but sane defaults for stable operations have been chosen.
|
||||
Currently, libfaketime does not use autotools yet, so there is
|
||||
_no_ ./configure step, but "make" and "make test" will work as expected.
|
||||
|
||||
For "make test", an optional environment variable FAKETIME_TESTLIB can
|
||||
be set, pointing to the path and filename of the libfaketime library
|
||||
to be used for tests; the default is "../src/libfaketime.so.1".
|
||||
|
||||
|
||||
However, one problem makes it somewhat difficult to get libfaketime
|
||||
working on different platforms:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH FAKETIME "1" "August 2019" "faketime 0.9.8" wolfcw
|
||||
.TH FAKETIME "1" "February 2021" "faketime 0.9.9" wolfcw
|
||||
.SH NAME
|
||||
faketime \- manipulate the system time for a given command
|
||||
.SH SYNOPSIS
|
||||
@@ -71,7 +71,7 @@ re-initialized. Some programs may dynamically load system libraries, such as lib
|
||||
.SH "REPORTING BUGS"
|
||||
Please use https://github.com/wolfcw/libfaketime/issues
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2003-2013 by the libfaketime authors.
|
||||
Copyright \(co 2003-2021 by the libfaketime authors.
|
||||
.PP
|
||||
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You may redistribute copies of faketime under the
|
||||
|
||||
12
src/Makefile
12
src/Makefile
@@ -6,6 +6,11 @@
|
||||
# FAKE_STAT
|
||||
# - Enables time faking also for files' timestamps.
|
||||
#
|
||||
# FAKE_FILE_TIMESTAMPS, FAKE_UTIME
|
||||
# - Enables time faking for the utime* functions. If enabled via
|
||||
# FAKE_UTIME define instead of FAKE_FILE_TIMESTAMPS, the faking
|
||||
# defaults to off without FAKE_UTIME in the environment.
|
||||
#
|
||||
# NO_ATFILE
|
||||
# - Disables support for the fstatat() group of functions
|
||||
#
|
||||
@@ -33,6 +38,9 @@
|
||||
# FAKE_SETTIME
|
||||
# - Intercept clock_settime(), settimeofday(), and adjtime()
|
||||
#
|
||||
# FAKE_RANDOM
|
||||
# - Intercept getrandom()
|
||||
#
|
||||
# FORCE_MONOTONIC_FIX
|
||||
# - If the test program hangs forever on
|
||||
# " pthread_cond_timedwait: CLOCK_MONOTONIC test
|
||||
@@ -41,7 +49,7 @@
|
||||
# (This is a platform-specific issue we cannot handle at run-time.)
|
||||
#
|
||||
# MULTI_ARCH
|
||||
# - If MULTI_ARCH is set, the faketime wrapper program will put a literal
|
||||
# - If MULTI_ARCH is set, the faketime wrapper program will put a literal
|
||||
# $LIB into the LD_PRELOAD environment variable it creates, which makes
|
||||
# ld automatically choose the correct library version to use for the
|
||||
# target binary. Use for Linux platforms with Multi-Arch support only!
|
||||
@@ -72,7 +80,7 @@ PREFIX ?= /usr/local
|
||||
LIBDIRNAME ?= /lib/faketime
|
||||
PLATFORM ?=$(shell uname)
|
||||
|
||||
CFLAGS += -std=gnu99 -Wall -Wextra -Werror -Wno-nonnull-compare -DFAKE_PTHREAD -DFAKE_STAT -DFAKE_SLEEP -DFAKE_TIMERS -DFAKE_INTERNAL_CALLS -fPIC -DPREFIX='"'$(PREFIX)'"' -DLIBDIRNAME='"'$(LIBDIRNAME)'"' $(FAKETIME_COMPILE_CFLAGS)
|
||||
CFLAGS += -std=gnu99 -Wall -Wextra -Werror -Wno-nonnull-compare -DFAKE_PTHREAD -DFAKE_STAT -DFAKE_UTIME -DFAKE_SLEEP -DFAKE_TIMERS -DFAKE_INTERNAL_CALLS -fPIC -DPREFIX='"'$(PREFIX)'"' -DLIBDIRNAME='"'$(LIBDIRNAME)'"' $(FAKETIME_COMPILE_CFLAGS)
|
||||
ifeq ($(PLATFORM),SunOS)
|
||||
CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=600
|
||||
endif
|
||||
|
||||
@@ -39,7 +39,7 @@ INSTALL ?= install
|
||||
PREFIX ?= /usr/local
|
||||
|
||||
CFLAGS += -DFAKE_SLEEP -DFAKE_INTERNAL_CALLS -DPREFIX='"'${PREFIX}'"' $(FAKETIME_COMPILE_CFLAGS)
|
||||
LIB_LDFLAGS += -dynamiclib -current_version 0.9.8 -compatibility_version 0.7
|
||||
LIB_LDFLAGS += -dynamiclib -current_version 0.9.9 -compatibility_version 0.7
|
||||
|
||||
SONAME = 1
|
||||
LIBS = libfaketime.${SONAME}.dylib
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* libfaketime wrapper command
|
||||
*
|
||||
* This file is part of libfaketime, version 0.9.8
|
||||
* This file is part of libfaketime, version 0.9.9
|
||||
*
|
||||
* libfaketime is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License v2 as published by the
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
#include "faketime_common.h"
|
||||
|
||||
const char version[] = "0.9.7";
|
||||
const char version[] = "0.9.9";
|
||||
|
||||
#ifdef __APPLE__
|
||||
static const char *date_cmd = "gdate";
|
||||
@@ -93,11 +93,11 @@ static void cleanup_shobjs()
|
||||
{
|
||||
if (-1 == sem_unlink(sem_name))
|
||||
{
|
||||
perror("sem_unlink");
|
||||
perror("faketime: sem_unlink");
|
||||
}
|
||||
if (-1 == shm_unlink(shm_name))
|
||||
{
|
||||
perror("shm_unlink");
|
||||
perror("faketime: shm_unlink");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ int main (int argc, char **argv)
|
||||
close(pfds[0]); /* we don't need this */
|
||||
if (EXIT_SUCCESS != execlp(date_cmd, date_cmd, "-d", argv[curr_opt], "+%s",(char *) NULL))
|
||||
{
|
||||
perror("Running (g)date failed");
|
||||
perror("faketime: Running (g)date failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
@@ -223,7 +223,7 @@ int main (int argc, char **argv)
|
||||
|
||||
if (SEM_FAILED == (sem = sem_open(sem_name, O_CREAT|O_EXCL, S_IWUSR|S_IRUSR, 1)))
|
||||
{
|
||||
perror("sem_open");
|
||||
perror("faketime: sem_open");
|
||||
fprintf(stderr, "The faketime wrapper only works on platforms that support the sem_open()\nsystem call. However, you may LD_PRELOAD libfaketime without using this wrapper.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -231,10 +231,10 @@ int main (int argc, char **argv)
|
||||
/* create shm */
|
||||
if (-1 == (shm_fd = shm_open(shm_name, O_CREAT|O_EXCL|O_RDWR, S_IWUSR|S_IRUSR)))
|
||||
{
|
||||
perror("shm_open");
|
||||
perror("faketime: shm_open");
|
||||
if (-1 == sem_unlink(argv[2]))
|
||||
{
|
||||
perror("sem_unlink");
|
||||
perror("faketime: sem_unlink");
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -242,7 +242,7 @@ int main (int argc, char **argv)
|
||||
/* set shm size */
|
||||
if (-1 == ftruncate(shm_fd, sizeof(uint64_t)))
|
||||
{
|
||||
perror("ftruncate");
|
||||
perror("faketime: ftruncate");
|
||||
cleanup_shobjs();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -251,14 +251,14 @@ int main (int argc, char **argv)
|
||||
if (MAP_FAILED == (ft_shared = mmap(NULL, sizeof(struct ft_shared_s), PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED, shm_fd, 0)))
|
||||
{
|
||||
perror("mmap");
|
||||
perror("faketime: mmap");
|
||||
cleanup_shobjs();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (sem_wait(sem) == -1)
|
||||
{
|
||||
perror("sem_wait");
|
||||
perror("faketime: sem_wait");
|
||||
cleanup_shobjs();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -275,14 +275,14 @@ int main (int argc, char **argv)
|
||||
|
||||
if (-1 == munmap(ft_shared, (sizeof(struct ft_shared_s))))
|
||||
{
|
||||
perror("munmap");
|
||||
perror("faketime: munmap");
|
||||
cleanup_shobjs();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (sem_post(sem) == -1)
|
||||
{
|
||||
perror("semop");
|
||||
perror("faketime: semop");
|
||||
cleanup_shobjs();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -347,7 +347,7 @@ int main (int argc, char **argv)
|
||||
close(keepalive_fds[0]); /* only parent needs to read this */
|
||||
if (EXIT_SUCCESS != execvp(argv[curr_opt], &argv[curr_opt]))
|
||||
{
|
||||
perror("Running specified command failed");
|
||||
perror("faketime: Running specified command failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of libfaketime, version 0.9.8
|
||||
* This file is part of libfaketime, version 0.9.9
|
||||
*
|
||||
* libfaketime is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License v2 as published by the
|
||||
@@ -111,6 +111,10 @@ typedef int clockid_t;
|
||||
#define CLOCK_MONOTONIC_RAW (CLOCK_MONOTONIC + 1)
|
||||
#endif
|
||||
|
||||
#if defined FAKE_UTIME && !defined FAKE_FILE_TIMESTAMPS
|
||||
#define FAKE_FILE_TIMESTAMPS
|
||||
#endif
|
||||
|
||||
#ifdef FAKE_FILE_TIMESTAMPS
|
||||
struct utimbuf {
|
||||
time_t actime; /* access time */
|
||||
@@ -118,6 +122,10 @@ struct utimbuf {
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef FAKE_RANDOM
|
||||
#include <sys/random.h>
|
||||
#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
|
||||
@@ -211,6 +219,12 @@ static clock_serv_t clock_serv_real;
|
||||
#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);
|
||||
static int (*real_utimensat) (int dirfd, const char *filename, const struct timespec times[2], int flags);
|
||||
static int (*real_futimens) (int fd, const struct timespec times[2]);
|
||||
#endif
|
||||
|
||||
#ifdef FAKE_RANDOM
|
||||
static ssize_t (*real_getrandom) (void *buf, size_t buflen, unsigned int flags);
|
||||
#endif
|
||||
|
||||
static int initialized = 0;
|
||||
@@ -600,8 +614,15 @@ static void next_time(struct timespec *tp, struct timespec *ticklen)
|
||||
/* lock */
|
||||
if (sem_wait(shared_sem) == -1)
|
||||
{
|
||||
perror("libfaketime: In next_time(), sem_wait failed");
|
||||
exit(1);
|
||||
if (errno == EINTR)
|
||||
{
|
||||
return next_time(tp, ticklen);
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("libfaketime: In next_time(), sem_wait failed");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
/* calculate and update elapsed time */
|
||||
timespecmul(ticklen, ft_shared->ticks, &inc);
|
||||
@@ -637,8 +658,15 @@ static void save_time(struct timespec *tp)
|
||||
/* lock */
|
||||
if (sem_wait(shared_sem) == -1)
|
||||
{
|
||||
perror("libfaketime: In save_time(), sem_wait failed");
|
||||
exit(1);
|
||||
if (errno == EINTR)
|
||||
{
|
||||
return save_time(tp);
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("libfaketime: In save_time(), sem_wait failed");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
lseek(outfile, 0, SEEK_END);
|
||||
@@ -675,8 +703,15 @@ static bool load_time(struct timespec *tp)
|
||||
/* lock */
|
||||
if (sem_wait(shared_sem) == -1)
|
||||
{
|
||||
perror("libfaketime: In load_time(), sem_wait failed");
|
||||
exit(1);
|
||||
if (errno == EINTR)
|
||||
{
|
||||
return load_time(tp);
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("libfaketime: In load_time(), sem_wait failed");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ((sizeof(stss[0]) * (ft_shared->file_idx + 1)) > infile_size)
|
||||
@@ -736,6 +771,7 @@ static bool load_time(struct timespec *tp)
|
||||
#include <sys/stat.h>
|
||||
|
||||
static int fake_stat_disabled = 0;
|
||||
static int fake_utime_disabled = 1;
|
||||
static bool user_per_tick_inc_set_backup = false;
|
||||
|
||||
void lock_for_stat()
|
||||
@@ -744,8 +780,15 @@ void lock_for_stat()
|
||||
{
|
||||
if (sem_wait(shared_sem) == -1)
|
||||
{
|
||||
perror("libfaketime: In lock_for_stat(), sem_wait failed");
|
||||
exit(1);
|
||||
if (errno == EINTR)
|
||||
{
|
||||
return lock_for_stat();
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("libfaketime: In lock_for_stat(), sem_wait failed");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
user_per_tick_inc_set_backup = user_per_tick_inc_set;
|
||||
@@ -1087,14 +1130,21 @@ int utime(const char *filename, const struct utimbuf *times)
|
||||
|
||||
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)
|
||||
if (fake_utime_disabled)
|
||||
{
|
||||
return -1;
|
||||
if (times == NULL)
|
||||
{ /* The user wants their given fake times left alone but they requested NOW, so turn it into fake NOW */
|
||||
ntbuf.actime = ntbuf.modtime = time(NULL);
|
||||
times = &ntbuf;
|
||||
}
|
||||
}
|
||||
|
||||
else if (times != NULL)
|
||||
{
|
||||
ntbuf.actime = times->actime - user_offset.tv_sec;
|
||||
ntbuf.modtime = times->modtime - user_offset.tv_sec;
|
||||
times = &ntbuf;
|
||||
}
|
||||
DONT_FAKE_TIME(result = real_utime(filename, times));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1114,17 +1164,105 @@ int utimes(const char *filename, const struct timeval times[2])
|
||||
|
||||
int result;
|
||||
struct timeval tn[2];
|
||||
struct timeval user_offset2;
|
||||
user_offset2.tv_sec = user_offset.tv_sec;
|
||||
user_offset2.tv_usec = 0;
|
||||
timersub(×[0], &user_offset2, &tn[0]);
|
||||
timersub(×[1], &user_offset2, &tn[1]);
|
||||
DONT_FAKE_TIME(result = real_utimes(filename, tn));
|
||||
if (result == -1)
|
||||
if (fake_utime_disabled)
|
||||
{
|
||||
return -1;
|
||||
if (times == NULL)
|
||||
{ /* The user wants their given fake times left alone but they requested NOW, so turn it into fake NOW */
|
||||
fake_gettimeofday(&tn[0]);
|
||||
tn[1] = tn[0];
|
||||
times = tn;
|
||||
}
|
||||
}
|
||||
else if (times != NULL)
|
||||
{
|
||||
struct timeval user_offset2;
|
||||
user_offset2.tv_sec = user_offset.tv_sec;
|
||||
user_offset2.tv_usec = user_offset.tv_nsec / 1000;
|
||||
timersub(×[0], &user_offset2, &tn[0]);
|
||||
timersub(×[1], &user_offset2, &tn[1]);
|
||||
times = tn;
|
||||
}
|
||||
DONT_FAKE_TIME(result = real_utimes(filename, times));
|
||||
return result;
|
||||
}
|
||||
|
||||
/* This conditionally offsets 2 timespec values. The caller's out_times array
|
||||
* always contains valid translated values, even if in_times was NULL. */
|
||||
static void fake_two_timespec(const struct timespec in_times[2], struct timespec out_times[2])
|
||||
{
|
||||
if (in_times == NULL) /* Translate NULL into 2 UTIME_NOW values */
|
||||
{
|
||||
out_times[0].tv_sec = out_times[1].tv_sec = 0;
|
||||
out_times[0].tv_nsec = out_times[1].tv_nsec = UTIME_NOW;
|
||||
in_times = out_times;
|
||||
}
|
||||
struct timespec now;
|
||||
now.tv_nsec = UTIME_OMIT; /* Wait to grab the current time to see if it's actually needed */
|
||||
int j;
|
||||
for (j = 0; j <= 1; j++)
|
||||
{
|
||||
/* We need to preserve 2 special time values in addition to when the user disables utime offsets */
|
||||
if (fake_utime_disabled || in_times[j].tv_nsec == UTIME_OMIT || in_times[j].tv_nsec == UTIME_NOW)
|
||||
{
|
||||
if (fake_utime_disabled && in_times[j].tv_nsec == UTIME_NOW)
|
||||
{ /* The user wants their given fake times left alone but they requested NOW, so turn it into fake NOW */
|
||||
if (now.tv_nsec == UTIME_OMIT) /* did we grab "now" yet? */
|
||||
{
|
||||
DONT_FAKE_TIME(real_clock_gettime(CLOCK_REALTIME, &now));
|
||||
}
|
||||
timeradd2(&now, &user_offset, &out_times[j], n);
|
||||
}
|
||||
else if (out_times != in_times)
|
||||
{ /* Just preserve the input value */
|
||||
out_times[j] = in_times[j];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
timersub2(&in_times[j], &user_offset, &out_times[j], n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int utimensat(int dirfd, const char *filename, const struct timespec times[2], int flags)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
ftpl_init();
|
||||
}
|
||||
if (NULL == real_utimensat)
|
||||
{ /* dlsym() failed */
|
||||
#ifdef DEBUG
|
||||
(void) fprintf(stderr, "faketime problem: original utimensat() not found.\n");
|
||||
#endif
|
||||
return -1; /* propagate error to caller */
|
||||
}
|
||||
|
||||
int result;
|
||||
struct timespec tn[2];
|
||||
fake_two_timespec(times, tn);
|
||||
DONT_FAKE_TIME(result = real_utimensat(dirfd, filename, tn, flags));
|
||||
return result;
|
||||
}
|
||||
|
||||
int futimens(int fd, const struct timespec times[2])
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
ftpl_init();
|
||||
}
|
||||
if (NULL == real_futimens)
|
||||
{ /* dlsym() failed */
|
||||
#ifdef DEBUG
|
||||
(void) fprintf(stderr, "faketime problem: original futimens() not found.\n");
|
||||
#endif
|
||||
return -1; /* propagate error to caller */
|
||||
}
|
||||
|
||||
int result;
|
||||
struct timespec tn[2];
|
||||
fake_two_timespec(times, tn);
|
||||
DONT_FAKE_TIME(result = real_futimens(fd, tn));
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
@@ -2273,6 +2411,8 @@ static void ftpl_init(void)
|
||||
#ifdef FAKE_FILE_TIMESTAMPS
|
||||
real_utimes = dlsym(RTLD_NEXT, "utimes");
|
||||
real_utime = dlsym(RTLD_NEXT, "utime");
|
||||
real_utimensat = dlsym(RTLD_NEXT, "utimensat");
|
||||
real_futimens = dlsym(RTLD_NEXT, "futimens");
|
||||
#endif
|
||||
#if defined(__alpha__) && defined(__GLIBC__)
|
||||
real_gettimeofday = dlvsym(RTLD_NEXT, "gettimeofday", "GLIBC_2.1");
|
||||
@@ -2308,6 +2448,11 @@ static void ftpl_init(void)
|
||||
# endif
|
||||
real___clock_gettime = dlsym(RTLD_NEXT, "__clock_gettime");
|
||||
#endif
|
||||
|
||||
#ifdef FAKE_RANDOM
|
||||
real_getrandom = dlsym(RTLD_NEXT, "getrandom");
|
||||
#endif
|
||||
|
||||
#ifdef FAKE_PTHREAD
|
||||
|
||||
#ifdef __GLIBC__
|
||||
@@ -2379,6 +2524,22 @@ static void ftpl_init(void)
|
||||
fake_stat_disabled = 1; //Note that this is NOT re-checked
|
||||
}
|
||||
#endif
|
||||
#if defined FAKE_FILE_TIMESTAMPS
|
||||
#ifndef FAKE_UTIME
|
||||
fake_utime_disabled = 0; // Defaults to enabled w/o FAKE_UTIME define
|
||||
#endif
|
||||
if ((tmp_env = getenv("FAKE_UTIME")) != NULL) //Note that this is NOT re-checked
|
||||
{
|
||||
if (!*tmp_env || *tmp_env == 'y' || *tmp_env == 'Y' || *tmp_env == 't' || *tmp_env == 'T')
|
||||
{ /* an empty string or a yes/true value turns off disabling */
|
||||
fake_utime_disabled = 0;
|
||||
}
|
||||
else
|
||||
{ /* Any other non-number disables the utime functions, but we also support FAKE_UTIME=1 to enable */
|
||||
fake_utime_disabled = !atoi(tmp_env);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((tmp_env = getenv("FAKETIME_CACHE_DURATION")) != NULL)
|
||||
{
|
||||
@@ -2687,6 +2848,9 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp)
|
||||
static time_t last_data_fetch = 0; /* not fetched previously at first call */
|
||||
static int cache_expired = 1; /* considered expired at first call */
|
||||
|
||||
/* Karl Chan's v0.8 sanity check moved here for 0.9.9 */
|
||||
if (tp == NULL) return -1;
|
||||
|
||||
/* create a copy of the timespec containing the real system time for clk_id */
|
||||
struct timespec tp_save;
|
||||
tp_save.tv_sec = tp->tv_sec;
|
||||
@@ -2703,11 +2867,8 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sanity check by Karl Chan since v0.8 */
|
||||
if (tp == NULL) return -1;
|
||||
|
||||
// {ret = value; goto abort;} to call matching pthread_cleanup_pop and return value
|
||||
int ret = INT_MAX;
|
||||
volatile int ret = INT_MAX;
|
||||
|
||||
#ifdef PTHREAD_SINGLETHREADED_TIME
|
||||
static pthread_mutex_t time_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
@@ -3209,6 +3370,17 @@ int pthread_cond_init_232(pthread_cond_t *restrict cond, const pthread_condattr_
|
||||
clockid_t clock_id;
|
||||
int result;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
ftpl_init();
|
||||
}
|
||||
if (NULL == real_pthread_cond_init_232)
|
||||
{ /* dlsym() failed */
|
||||
#ifdef DEBUG
|
||||
(void) fprintf(stderr, "faketime problem: original pthread_cond_init (@@GLIBC_2.3.2, fallback) not found.\n");
|
||||
#endif
|
||||
return -1; /* propagate error to caller */
|
||||
}
|
||||
result = real_pthread_cond_init_232(cond, attr);
|
||||
|
||||
if (result != 0 || attr == NULL)
|
||||
@@ -3394,9 +3566,46 @@ int clock_settime(clockid_t clk_id, const struct timespec *tp) {
|
||||
offset += (double) nsec_diff/SEC_TO_nSEC;
|
||||
snprintf(newenv_string, 255, "%+f", offset);
|
||||
|
||||
parse_config_file = false; /* #247: make sure environment takes precedence */
|
||||
setenv("FAKETIME", newenv_string, 1);
|
||||
force_cache_expiration = 1; /* make sure it becomes effective immediately */
|
||||
|
||||
/* If FAKETIME_TIMESTAMP_FILE was given in environment,
|
||||
* and if FAKETIME_UPDATE_TIMESTAMP_FILE=1, then update it.
|
||||
* This allows other process instances to share the same time. */
|
||||
if ( (getenv("FAKETIME_TIMESTAMP_FILE") != NULL)
|
||||
&& (*getenv("FAKETIME_TIMESTAMP_FILE") != '\0')
|
||||
&& (getenv("FAKETIME_UPDATE_TIMESTAMP_FILE") != NULL)
|
||||
&& (strcmp(getenv("FAKETIME_UPDATE_TIMESTAMP_FILE"), "1") == 0))
|
||||
{
|
||||
const char *error = NULL;
|
||||
FILE *envfile;
|
||||
static char custom_filename[BUFSIZ];
|
||||
(void) snprintf(custom_filename, BUFSIZ, "%s", getenv("FAKETIME_TIMESTAMP_FILE"));
|
||||
|
||||
if ((envfile = fopen(custom_filename, "wt")) != NULL)
|
||||
{
|
||||
if (fprintf(envfile, "%+f\n", offset) < 0)
|
||||
{
|
||||
error = "to write to file";
|
||||
}
|
||||
if (fclose(envfile) != 0)
|
||||
{
|
||||
error = "to close file";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error = "to open file";
|
||||
}
|
||||
if (error)
|
||||
{
|
||||
fprintf(stderr, "libfaketime: In clock_settime(), failed to "
|
||||
"%s while updating FAKETIME_TIMESTAMP_FILE (`%s'): %s\n",
|
||||
error, getenv("FAKETIME_TIMESTAMP_FILE"), strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3445,6 +3654,41 @@ int adjtime (const struct timeval *delta, struct timeval *olddelta)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FAKE_RANDOM
|
||||
/*
|
||||
Local copy of
|
||||
Middle Square Weyl Sequence Random Number Generator
|
||||
Copyright (c) 2014-2020 Bernard Widynski
|
||||
License: GNU GPL v3
|
||||
see https://mswsrng.wixsite.com/rand
|
||||
|
||||
adapted to take the seed s as a parameter and return only a byte
|
||||
*/
|
||||
inline static uint32_t fakerandom_msws(uint64_t s) {
|
||||
static uint64_t x = 0, w = 0;
|
||||
x *= x; x += (w += s);
|
||||
x = (x>>32) | (x<<32);
|
||||
return (char) x & 0xFF;
|
||||
}
|
||||
|
||||
|
||||
ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) {
|
||||
char *seedstring = getenv("FAKERANDOM_SEED");
|
||||
char *b = buf;
|
||||
|
||||
if (seedstring != NULL) {
|
||||
long long int seed = strtoll(seedstring, NULL, 0);
|
||||
for (size_t i = 0; i < buflen; i++) {
|
||||
b[i] = fakerandom_msws(seed);
|
||||
}
|
||||
return buflen;
|
||||
}
|
||||
else { /* if no FAKERANDOM_SEED was given, use the original function */
|
||||
return real_getrandom(buf, buflen, flags);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Editor modelines
|
||||
*
|
||||
|
||||
@@ -22,8 +22,14 @@ test: timetest functest
|
||||
functest:
|
||||
./testframe.sh functests
|
||||
|
||||
getrandom_test: getrandom_test.c
|
||||
${CC} -o $@ ${CFLAGS} $<
|
||||
|
||||
randomtest: getrandom_test
|
||||
./randomtest.sh
|
||||
|
||||
clean:
|
||||
@rm -f ${OBJ} timetest
|
||||
@rm -f ${OBJ} timetest getrandom_test
|
||||
|
||||
distclean: clean
|
||||
@echo
|
||||
|
||||
@@ -39,7 +39,8 @@ sunos_fakecmd()
|
||||
linuxlike_fakecmd()
|
||||
{
|
||||
typeset timestring="$1"; shift
|
||||
typeset fakelib=../src/libfaketime.so.1
|
||||
FTPL="${FAKETIME_TESTLIB:-../src/libfaketime.so.1}"
|
||||
typeset fakelib="$FTPL"
|
||||
export LD_PRELOAD=$fakelib
|
||||
FAKETIME="$timestring" \
|
||||
"$@"
|
||||
|
||||
25
test/getrandom_test.c
Normal file
25
test/getrandom_test.c
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/random.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main() {
|
||||
char *buf = calloc(100, 1);
|
||||
size_t buflen = 100;
|
||||
unsigned flags = GRND_NONBLOCK;
|
||||
|
||||
fprintf(stdout, "Before getrandom:\n");
|
||||
for (size_t i=0; i < buflen; i++) { fprintf(stdout, "%hhu ", buf[i]); }
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
int result = getrandom(buf, buflen, flags);
|
||||
fprintf(stdout, "getrandom() result: %d\n", result);
|
||||
if (result == -1) perror("getrandom() unsuccessful");
|
||||
|
||||
|
||||
fprintf(stdout, "After getrandom:\n");
|
||||
for (size_t i=0; i < buflen; i++) { fprintf(stdout, "%hhu ", buf[i]); }
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
31
test/randomtest.sh
Executable file
31
test/randomtest.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
|
||||
FTPL="${FAKETIME_TESTLIB:-../src/libfaketime.so.1}"
|
||||
|
||||
error=0
|
||||
./getrandom_test > run0
|
||||
FAKERANDOM_SEED=0x12345678DEADBEEF LD_PRELOAD="$FTPL" ./getrandom_test > run1
|
||||
FAKERANDOM_SEED=0x12345678DEADBEEF LD_PRELOAD="$FTPL" ./getrandom_test > run2
|
||||
FAKERANDOM_SEED=0x0000000000000000 LD_PRELOAD="$FTPL" ./getrandom_test > run3
|
||||
|
||||
|
||||
if diff -u run0 run1 > /dev/null; then
|
||||
error=1
|
||||
printf >&2 'test run without a seed produced the same data as a run with a seed!\n'
|
||||
fi
|
||||
if ! diff -u run1 run2; then
|
||||
error=2
|
||||
printf >&2 'test runs with identical seeds differed!\n'
|
||||
fi
|
||||
if diff -u run2 run3 >/dev/null; then
|
||||
error=3
|
||||
printf >&2 'test runs with different seeds produced the same data!\n'
|
||||
fi
|
||||
|
||||
rm -f run0 run1 run2 run3
|
||||
|
||||
if [ 0 = $error ]; then
|
||||
printf 'getrandom interception test successful.\n'
|
||||
fi
|
||||
|
||||
exit $error
|
||||
34
test/test.sh
34
test/test.sh
@@ -1,14 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
FTPL="${FAKETIME_TESTLIB:-../src/libfaketime.so.1}"
|
||||
|
||||
if [ -f /etc/faketimerc ] ; then
|
||||
echo "Running the test program with your system-wide default in /etc/faketimerc"
|
||||
echo "\$ LD_PRELOAD=../src/libfaketime.so.1 ./timetest"
|
||||
LD_PRELOAD=../src/libfaketime.so.1 ./timetest
|
||||
echo "\$ LD_PRELOAD=$FTPL ./timetest"
|
||||
LD_PRELOAD="$FTPL" ./timetest
|
||||
echo
|
||||
else
|
||||
echo "Running the test program with no faked time specified"
|
||||
echo "\$ LD_PRELOAD=../src/libfaketime.so.1 ./timetest"
|
||||
LD_PRELOAD=../src/libfaketime.so.1 ./timetest
|
||||
echo "\$ LD_PRELOAD=$FTPL ./timetest"
|
||||
LD_PRELOAD="$FTPL" ./timetest
|
||||
echo
|
||||
fi
|
||||
|
||||
@@ -16,48 +18,48 @@ echo "==========================================================================
|
||||
echo
|
||||
|
||||
echo "Running the test program with absolute date 2003-01-01 10:00:05 specified"
|
||||
echo "\$ LD_PRELOAD=../src/libfaketime.so.1 FAKETIME=\"2003-01-01 10:00:05\" ./timetest"
|
||||
LD_PRELOAD=../src/libfaketime.so.1 FAKETIME="2003-01-01 10:00:05" ./timetest
|
||||
echo "\$ LD_PRELOAD=$FTPL FAKETIME=\"2003-01-01 10:00:05\" ./timetest"
|
||||
LD_PRELOAD="$FTPL" FAKETIME="2003-01-01 10:00:05" ./timetest
|
||||
echo
|
||||
|
||||
echo "============================================================================="
|
||||
echo
|
||||
|
||||
echo "Running the test program with START date @2005-03-29 14:14:14 specified"
|
||||
echo "\$ LD_PRELOAD=../src/libfaketime.so.1 FAKETIME=\"@2005-03-29 14:14:14\" ./timetest"
|
||||
LD_PRELOAD=../src/libfaketime.so.1 FAKETIME="@2005-03-29 14:14:14" ./timetest
|
||||
echo "\$ LD_PRELOAD=$FTPL FAKETIME=\"@2005-03-29 14:14:14\" ./timetest"
|
||||
LD_PRELOAD="$FTPL" FAKETIME="@2005-03-29 14:14:14" ./timetest
|
||||
echo
|
||||
|
||||
echo "============================================================================="
|
||||
echo
|
||||
|
||||
echo "Running the test program with 10 days negative offset specified"
|
||||
echo "LD_PRELOAD=../src/libfaketime.so.1 FAKETIME=\"-10d\" ./timetest"
|
||||
LD_PRELOAD=../src/libfaketime.so.1 FAKETIME="-10d" ./timetest
|
||||
echo "LD_PRELOAD=$FTPL FAKETIME=\"-10d\" ./timetest"
|
||||
LD_PRELOAD="$FTPL" FAKETIME="-10d" ./timetest
|
||||
echo
|
||||
|
||||
echo "============================================================================="
|
||||
echo
|
||||
|
||||
echo "Running the test program with 10 days negative offset specified, and FAKE_STAT disabled"
|
||||
echo "\$ LD_PRELOAD=../src/libfaketime.so.1 FAKETIME=\"-10d\" NO_FAKE_STAT=1 ./timetest"
|
||||
LD_PRELOAD=../src/libfaketime.so.1 FAKETIME="-10d" NO_FAKE_STAT=1 ./timetest
|
||||
echo "\$ LD_PRELOAD=$FTPL FAKETIME=\"-10d\" NO_FAKE_STAT=1 ./timetest"
|
||||
LD_PRELOAD="$FTPL" FAKETIME="-10d" NO_FAKE_STAT=1 ./timetest
|
||||
echo
|
||||
|
||||
echo "============================================================================="
|
||||
echo
|
||||
|
||||
echo "Running the test program with 10 days positive offset specified, and speed-up factor"
|
||||
echo "\$ LD_PRELOAD=../src/libfaketime.so.1 FAKETIME=\"+10d x1\" ./timetest"
|
||||
LD_PRELOAD=../src/libfaketime.so.1 FAKETIME="+10d x1" NO_FAKE_STAT=1 ./timetest
|
||||
echo "\$ LD_PRELOAD=$FTPL FAKETIME=\"+10d x1\" ./timetest"
|
||||
LD_PRELOAD="$FTPL" FAKETIME="+10d x1" NO_FAKE_STAT=1 ./timetest
|
||||
echo
|
||||
|
||||
echo "============================================================================="
|
||||
echo
|
||||
|
||||
echo "Running the 'date' command with 15 days negative offset specified"
|
||||
echo "\$ LD_PRELOAD=../src/libfaketime.so.1 FAKETIME=\"-15d\" date"
|
||||
LD_PRELOAD=../src/libfaketime.so.1 FAKETIME="-15d" date
|
||||
echo "\$ LD_PRELOAD=$FTPL FAKETIME=\"-15d\" date"
|
||||
LD_PRELOAD="$FTPL" FAKETIME="-15d" date
|
||||
echo
|
||||
|
||||
echo "============================================================================="
|
||||
|
||||
@@ -216,7 +216,10 @@ printf("%s", 0 == 1 ? argv[0] : "");
|
||||
printf("time() : Current date and time: %s", ctime(&now));
|
||||
printf("time(NULL) : Seconds since Epoch : %u\n", (unsigned int)time(NULL));
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
ftime(&tb);
|
||||
#pragma GCC diagnostic pop
|
||||
printf("ftime() : Current date and time: %s", ctime(&tb.time));
|
||||
|
||||
printf("(Intentionally sleeping 2 seconds...)\n");
|
||||
@@ -243,7 +246,11 @@ printf("%s", 0 == 1 ? argv[0] : "");
|
||||
int timer_getoverrun_timerid1 = timer_getoverrun(timerid1);
|
||||
if (timer_getoverrun_timerid1 != 3)
|
||||
{
|
||||
#ifdef __GNU__
|
||||
printf("(Timer overruns are assumed to be fine on Hurd)\n");
|
||||
#else
|
||||
printf("timer_getoverrun(timerid1) FAILED, must be 3 but got: %d\n", timer_getoverrun_timerid1);
|
||||
#endif
|
||||
}
|
||||
|
||||
timer_gettime(timerid1, &its);
|
||||
|
||||
Reference in New Issue
Block a user