37 Commits

Author SHA1 Message Date
Wolfgang Hommel
3c0b101a84 Version bump to v0.9.9 2021-02-21 18:27:02 +01:00
Wolfgang Hommel
44a6d1f0fa Set FORCE_MONOTONIC_FIX for GitHub CI 2021-02-12 17:04:28 +01:00
Wolfgang Hommel
772d9523a7 Do not fail due to timer overrun counter mismatch on GNU/Hurd for now (#287) 2021-02-12 16:59:42 +01:00
Wolfgang Hommel
8b5519d496 Handle EINTR during sem_wait() in selected functions (addresses #291) 2021-02-09 20:16:08 +01:00
Wolfgang Hommel
3ba66842aa Make randomtest.sh use FAKETIME_TESTLIB like the rest of the test cases 2021-02-04 21:40:55 +01:00
Wolfgang Hommel
4359458c7c Merge pull request #289 from dkg/getrandom_test-cleanup
Ease build of getrandom_test
2021-02-04 21:39:02 +01:00
Wolfgang Hommel
726c4657fc Merge branch 'master' of github.com:wolfcw/libfaketime 2021-02-04 21:32:22 +01:00
Wolfgang Hommel
8853afb509 Added optional FAKETIME_TESTLIB environment variable for make test (#288) 2021-02-04 21:30:01 +01:00
Wolfgang Hommel
48f280ac86 Merge pull request #285 from dkg/fix-clobber
Try to fix warning about clobbering under optimization (Closes #284)
2021-02-04 20:07:56 +01:00
Wolfgang Hommel
47e6f5f33d Merge pull request #283 from dkg/update-version-number
fix embedded version number
2021-02-03 19:53:49 +01:00
Wolfgang Hommel
e4e5ea6211 Merge pull request #286 from dkg/speling
Fix spelling
2021-02-03 19:51:19 +01:00
Daniel Kahn Gillmor
206ae9ea80 Ease build of getrandom_test
In trying to test the experimental getrandom features, I found a few
minor problems.  These changes should make it easier to test.

After building, the developer can now just do:

    make -C test randomtest

This will do a basic verfication that the feature works as expected.

I haven't tried to integrate this with the overall "make test".  To do
that right, it should condition the test on the definition of
FAKE_RANDOM.
2021-02-03 13:12:32 -05:00
Daniel Kahn Gillmor
cce377b371 Fix spelling 2021-02-03 11:55:28 -05:00
Daniel Kahn Gillmor
5e6ed4cd2c Try to fix warning about clobbering under optimization (Closes #284)
Without this fix, when compiling with `-O1` or more, we see:

```
libfaketime.c: In function ‘fake_clock_gettime’:
libfaketime.c:2843:7: error: variable ‘ret’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered]
 2843 |   int ret = INT_MAX;
      |       ^~~
cc1: all warnings being treated as errors
```

This error doesn't happen when using `-O0`.

The warning appears to happen when the compiler optimizes `ret`
because it is the return value for the function call (meaning maybe
preserved in a register, or some other more risky placement that might
break during the `goto` error cases?).  Explicitly marking it as
volatile should keep the compiler from optimizing that way, regardless
of the level of optimization the user asks for.

I got the idea to use `volatile` here from the rather confused
discussion in
https://cboard.cprogramming.com/c-programming/147829-help-me-warning-argument-fmtstring-might-clobbered-longjmp-vfork.html

I admit I don't fully understand what's going on here, and would be
grateful for review by someone who understands the machinery here at a
deeper level than I do.
2021-02-02 20:14:37 -05:00
Daniel Kahn Gillmor
55e634a6ca fix embedded version number 2021-02-02 19:23:13 -05:00
Wolfgang Hommel
532816864e Merge pull request #278 from oxan/prefix-error-messages
faketime: Prefix error messages with faketime
2020-12-08 19:14:47 +01:00
Oxan van Leeuwen
4564afb924 faketime: Prefix error messages with faketime 2020-12-08 17:27:06 +01:00
Wolfgang Hommel
5b8673df54 Updated macOS-specific documentation, especially regarding SIP issues 2020-11-16 17:05:17 +01:00
Wolfgang Hommel
e00ba47ca9 Preliminary documentation related to #275 changes 2020-11-16 16:56:47 +01:00
Wolfgang Hommel
ca2f3fefa1 Preliminary support to intercept getrandom() #275 2020-11-15 21:57:10 +01:00
Wolfgang Hommel
dacc5866a7 Merge pull request #270 from sanjaymsh/ppc64le
Travis-ci: added support for ppc64le
2020-10-07 19:52:48 +02:00
sanjay-cpu
b35e7c8ca6 Travis-ci: added support for ppc64le 2020-10-07 08:28:41 +00:00
Wolfgang Hommel
25a60d0292 Merge pull request #261 from WayneD/master
Some fixes and improvements for utime functions.
2020-07-29 08:11:58 +02:00
Wayne Davison
d90c8c26d3 Some fixes and improvements for utime functions.
- Fix the utime() and utimes() functions to work with a NULL arg
  (which is a request for "now").
- Add missing utimensat() & futimens() functions.
- Add support for a FAKE_UTIME define and enable it by default.  This
  is like defining FAKE_FILE_TIMESTAMPS except that the code defaults
  to NO utime faking unless FAKE_UTIME environment var enables it.
- When utime values are not being faked, the use of a NULL arg or a
  UTIME_NOW nsec value gives the user NOW translated into their fake
  current time.  This is because the caller's fake times are otherwise
  being preserved, so we should help their NOW request also be handled
  as a fake time.
- Mention FAKE_FILE_TIMESTAMPS & FAKE_UTIME in the src/Makefile.
- Move a sanity check in fake_clock_gettime() to where it is actually
  prior to all the pointer dereferences it should protect.
- Get rid of an errant tab in the src/Makefile's comments.
2020-07-28 18:04:11 -07:00
Wolfgang Hommel
c683c81417 Merge pull request #257 from robinlinden/deprecated-func-warning
Fix make test build failure on gcc 9.3
2020-05-29 06:35:51 +02:00
Robin Linden
f19d68ea32 Fix make test build failure on gcc 9.3
On Ubuntu 20.04 using gcc 9.3, make test fails due to a deprecated
function (ftime) warning in combination with -Werror in timetest.c.
Since the warning is from a test testing that the deprecated function
can be replaced using LD_PRELOAD, I think it's reasonable to just
silence the warning in that case.
2020-05-28 23:26:25 +02:00
Wolfgang Hommel
c36674c27f remote automake branch workflow until work on it continues 2020-05-10 13:28:30 +02:00
Wolfgang Hommel
112809f986 Merge branch 'master' of github.com:wolfcw/libfaketime 2020-04-10 13:28:05 +02:00
Wolfgang Hommel
9498b2cacc add ./configure step to action for automake branch 2020-04-10 13:27:51 +02:00
Wolfgang Hommel
c9a3b1bace Merge pull request #248 from sdettmer/fix_settime_when_using_rcfile
Fixes #247, FAKE_SETTIME has effect even if rcfile is present
2020-04-09 19:53:06 +02:00
Wolfgang Hommel
834953480e Merge pull request #249 from sdettmer/settime_update_timestamp_file
settime functions support FAKETIME_UPDATE_TIMESTAMP_FILE (for #239).
2020-04-09 19:47:06 +02:00
Steffen Dettmer
c1d10321a7 settime functions support FAKETIME_UPDATE_TIMESTAMP_FILE (for #239).
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.
2020-04-09 16:06:32 +02:00
Steffen Dettmer
58ccfb6c27 Fixes #247, FAKE_SETTIME has effect even if rcfile is present 2020-04-09 13:04:40 +02:00
Wolfgang Hommel
1e25e1f042 fix for github action for automake branch 2020-04-09 11:41:01 +02:00
Wolfgang Hommel
690ed3f158 github action for automake branch 2020-04-09 06:41:10 +02:00
Wolfgang Hommel
d2f0daf092 Merge pull request #246 from sdettmer/dev/sde/pthread_cond_init_232_lazy_init
Add lazy ftpl_init() to pthread_cond_init_232(), fixes #245.
2020-04-08 20:11:57 +02:00
Steffen Dettmer
c5b5d0b56e Add lazy ftpl_init() to pthread_cond_init_232(), fixes #245. 2020-04-08 19:57:14 +02:00
18 changed files with 543 additions and 83 deletions

View File

@@ -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
View File

@@ -1,6 +1,7 @@
*.o
*.so.1
timetest
test/getrandom_test
src/libfaketime.dylib.1
src/libfaketime.1.dylib

View File

@@ -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
View File

@@ -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
View File

@@ -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
----------

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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(&times[0], &user_offset2, &tn[0]);
timersub(&times[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(&times[0], &user_offset2, &tn[0]);
timersub(&times[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
*

View File

@@ -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

View File

@@ -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
View 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
View 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

View File

@@ -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 "============================================================================="

View File

@@ -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);