mirror of
https://github.com/wolfcw/libfaketime.git
synced 2026-06-17 07:43:00 +03:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57de5bbe83 | ||
|
|
c2b5b71777 | ||
|
|
6c0947c86e | ||
|
|
b36ad2342c | ||
|
|
d40d0ebaa7 | ||
|
|
081845440b | ||
|
|
30207e8fdf |
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: FAKETIME_COMPILE_CFLAGS="-DFORCE_MONOTONIC_FIX" make
|
||||
run: make
|
||||
- name: make test
|
||||
run: make test
|
||||
|
||||
22
.gitignore
vendored
22
.gitignore
vendored
@@ -1,10 +1,30 @@
|
||||
*.o
|
||||
*.so.1
|
||||
timetest
|
||||
test/getrandom_test
|
||||
|
||||
src/libfaketime.dylib.1
|
||||
src/libfaketime.1.dylib
|
||||
src/core
|
||||
src/faketime
|
||||
|
||||
.vscode/
|
||||
|
||||
Makefile
|
||||
Makefile.in
|
||||
/aclocal.m4
|
||||
/autom4te.cache/
|
||||
/config.*
|
||||
/configure
|
||||
/depcomp
|
||||
/install-sh
|
||||
/libtool
|
||||
/ltmain.sh
|
||||
/m4/
|
||||
/missing
|
||||
/stamp-h?
|
||||
.deps/
|
||||
.dirstamp
|
||||
.libs/
|
||||
*.l[ao]
|
||||
compile
|
||||
test-driver
|
||||
|
||||
14
.travis.yml
14
.travis.yml
@@ -3,19 +3,15 @@ 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}
|
||||
- if [ "$TRAVIS_ARCH" = ppc64le ]; then
|
||||
FAKETIME_COMPILE_CFLAGS="-DFORCE_MONOTONIC_FIX -DFORCE_PTHREAD_NONVER" make;
|
||||
else
|
||||
FAKETIME_COMPILE_CFLAGS="-DFORCE_MONOTONIC_FIX" make;
|
||||
fi
|
||||
- sh ./build.sh init
|
||||
- ./configure
|
||||
- FAKETIME_COMPILE_CFLAGS="-DFORCE_MONOTONIC_FIX" make
|
||||
- cd test
|
||||
- make test
|
||||
- make distcheck
|
||||
|
||||
11
ChangeLog
Normal file
11
ChangeLog
Normal file
@@ -0,0 +1,11 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
Additional change history is viewable in the `NEWS` file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
### Changed
|
||||
- Mike Stemle added GNU autotools
|
||||
35
Makefile
35
Makefile
@@ -1,35 +0,0 @@
|
||||
INSTALL ?= install
|
||||
|
||||
UNAME=$(shell uname)
|
||||
SELECTOR:=$(shell if test "${UNAME}" = "Darwin" ; then echo "-f Makefile.OSX" ; fi)
|
||||
|
||||
all:
|
||||
$(MAKE) $(SELECTOR) -C src all
|
||||
|
||||
test:
|
||||
$(MAKE) $(SELECTOR) -C src all
|
||||
$(MAKE) $(SELECTOR) -C test all
|
||||
|
||||
install:
|
||||
$(MAKE) $(SELECTOR) -C src install
|
||||
$(MAKE) $(SELECTOR) -C man install
|
||||
$(INSTALL) -dm0755 "${DESTDIR}${PREFIX}/share/doc/faketime/"
|
||||
$(INSTALL) -m0644 README "${DESTDIR}${PREFIX}/share/doc/faketime/README"
|
||||
$(INSTALL) -m0644 NEWS "${DESTDIR}${PREFIX}/share/doc/faketime/NEWS"
|
||||
|
||||
uninstall:
|
||||
$(MAKE) $(SELECTOR) -C src uninstall
|
||||
$(MAKE) $(SELECTOR) -C man uninstall
|
||||
rm -f "${DESTDIR}${PREFIX}/share/doc/faketime/README"
|
||||
rm -f "${DESTDIR}${PREFIX}/share/doc/faketime/NEWS"
|
||||
rmdir "${DESTDIR}${PREFIX}/share/doc/faketime"
|
||||
|
||||
clean:
|
||||
$(MAKE) $(SELECTOR) -C src clean
|
||||
$(MAKE) $(SELECTOR) -C test clean
|
||||
|
||||
distclean:
|
||||
$(MAKE) $(SELECTOR) -C src distclean
|
||||
$(MAKE) $(SELECTOR) -C test distclean
|
||||
|
||||
.PHONY: all test install uninstall clean distclean
|
||||
4
Makefile.am
Normal file
4
Makefile.am
Normal file
@@ -0,0 +1,4 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
ACLOCAL_AMFLAGS=-I m4
|
||||
SUBDIRS=src test man
|
||||
EXTRA_DIST=README.developers README.OSX README.packagers TODO
|
||||
21
NEWS
21
NEWS
@@ -1,23 +1,10 @@
|
||||
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.
|
||||
Since 0.9.9:
|
||||
- Mike Stemle added GNU autotools
|
||||
- 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)
|
||||
|
||||
144
README
144
README
@@ -1,5 +1,5 @@
|
||||
libfaketime, version 0.9.9 (February 2021)
|
||||
==========================================
|
||||
libfaketime, version 0.9.8 (August 2019)
|
||||
========================================
|
||||
|
||||
|
||||
Content of this file:
|
||||
@@ -20,7 +20,6 @@ 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
|
||||
|
||||
@@ -107,8 +106,16 @@ documentation whether it can be achieved by using libfaketime directly.
|
||||
3. Installation
|
||||
---------------
|
||||
|
||||
Running "make" compiles both library versions and a test program, which it then
|
||||
also executes.
|
||||
This library supports GNU autotools, so you should be able to build it with:
|
||||
|
||||
sh ./build.sh init
|
||||
./configure
|
||||
make
|
||||
|
||||
After you have built the library, you may--optionally--run the tests with:
|
||||
|
||||
cd test
|
||||
make test
|
||||
|
||||
If the test works fine, you should copy the libfaketime libraries
|
||||
(libfaketime.so.1, and libfaketimeMT.so.1) to the place you want them in.
|
||||
@@ -131,14 +138,16 @@ not need this feature or if it confuses the application you want to use FTPL
|
||||
with, define the environment variable NO_FAKE_STAT, and the intercepted stat
|
||||
calls will be passed through unaltered.
|
||||
|
||||
On macOS, it is necessary to compile differently, due to the different
|
||||
behavior dyld has. Use the Makefile.OSX file provided to compile
|
||||
libfaketime.1.dylib. Additionally, instead of using LD_PRELOAD,
|
||||
the variable DYLD_INSERT_LIBRARIES should be set to the path to
|
||||
libfaketime.1.dylib, and the variable DYLD_FORCE_FLAT_NAMESPACE should be
|
||||
set (to anything). macOS users should read README.OSX for additional
|
||||
details.
|
||||
On macOS, instead of using LD_PRELOAD, the variable DYLD_INSERT_LIBRARIES
|
||||
should be set to the path to libfaketime.0.dylib, and the variable
|
||||
DYLD_FORCE_FLAT_NAMESPACE should be set (to anything). macOS users should
|
||||
read README.OSX for additional details.
|
||||
|
||||
NOTE: When committing, clean up potentially non-portable files with:
|
||||
|
||||
sh build.sh clean
|
||||
|
||||
This will clean up the build files which we don't want to version-control.
|
||||
|
||||
4. Usage
|
||||
--------
|
||||
@@ -188,21 +197,19 @@ 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 multiple ways to
|
||||
be loaded, but just report the real system time. There are three 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
|
||||
@@ -327,7 +334,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 explicit zero offset as a prefix in your FAKETIME.
|
||||
like "+0 x2", i.e., use an explizit zero offset as a prefix in your FAKETIME.
|
||||
|
||||
For testing, your should run a command like
|
||||
|
||||
@@ -371,8 +378,7 @@ 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 (especially when not using FAKETIME environment
|
||||
but configuration files, such as FAKETIME_TIMESTAMP_FILE).
|
||||
influence the performance.
|
||||
|
||||
|
||||
Setting FAKETIME by means of a file timestamp
|
||||
@@ -438,14 +444,9 @@ 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.
|
||||
|
||||
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
|
||||
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
|
||||
cases, you should occasionally delete
|
||||
|
||||
/dev/shm/faketime_shm_* and
|
||||
@@ -470,54 +471,9 @@ 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(). 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.
|
||||
settimeofday(), and adjtime(). Instead of passing the timestamp a
|
||||
program sets through to the system, only the FAKETIME environment
|
||||
variable will be adjusted accordingly.
|
||||
|
||||
|
||||
4f) Faking the date and time system-wide
|
||||
@@ -693,11 +649,6 @@ 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
|
||||
@@ -717,41 +668,6 @@ 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
|
||||
----------
|
||||
|
||||
|
||||
29
README.OSX
29
README.OSX
@@ -1,17 +1,10 @@
|
||||
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 Catalina currently.
|
||||
Developments and tests are done on Mojave 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
|
||||
@@ -46,18 +39,23 @@ Otherwise, you have to compile and install libfaketime manually; this
|
||||
will require a working installation of Xcode and its command line tools
|
||||
on your machine.
|
||||
|
||||
You can compile libfaketime by running the command
|
||||
This library now supports GNU autotools, so you can build it using:
|
||||
|
||||
sh build.sh init
|
||||
./configure
|
||||
make
|
||||
|
||||
in libfaketime's top-level directory.
|
||||
|
||||
The resulting library will be named libfaketime.1.dylib ; to check
|
||||
whether it works properly, run the test suite and verify whether its
|
||||
output is correct:
|
||||
|
||||
cd test
|
||||
make -f Makefile.OSX
|
||||
make test
|
||||
|
||||
NOTE: When committing, be sure to clean up potentially
|
||||
system-dependent files by running:
|
||||
|
||||
sh build.sh clean
|
||||
|
||||
|
||||
2) Using libfaketime from the command line on macOS
|
||||
@@ -145,13 +143,6 @@ 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,10 +14,6 @@ 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:
|
||||
|
||||
270
ar-lib
Executable file
270
ar-lib
Executable file
@@ -0,0 +1,270 @@
|
||||
#! /bin/sh
|
||||
# Wrapper for Microsoft lib.exe
|
||||
|
||||
me=ar-lib
|
||||
scriptversion=2012-03-01.08; # UTC
|
||||
|
||||
# Copyright (C) 2010-2018 Free Software Foundation, Inc.
|
||||
# Written by Peter Rosin <peda@lysator.liu.se>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
|
||||
# func_error message
|
||||
func_error ()
|
||||
{
|
||||
echo "$me: $1" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
file_conv=
|
||||
|
||||
# func_file_conv build_file
|
||||
# Convert a $build file to $host form and store it in $file
|
||||
# Currently only supports Windows hosts.
|
||||
func_file_conv ()
|
||||
{
|
||||
file=$1
|
||||
case $file in
|
||||
/ | /[!/]*) # absolute file, and not a UNC file
|
||||
if test -z "$file_conv"; then
|
||||
# lazily determine how to convert abs files
|
||||
case `uname -s` in
|
||||
MINGW*)
|
||||
file_conv=mingw
|
||||
;;
|
||||
CYGWIN*)
|
||||
file_conv=cygwin
|
||||
;;
|
||||
*)
|
||||
file_conv=wine
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
case $file_conv in
|
||||
mingw)
|
||||
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
|
||||
;;
|
||||
cygwin)
|
||||
file=`cygpath -m "$file" || echo "$file"`
|
||||
;;
|
||||
wine)
|
||||
file=`winepath -w "$file" || echo "$file"`
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# func_at_file at_file operation archive
|
||||
# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE
|
||||
# for each of them.
|
||||
# When interpreting the content of the @FILE, do NOT use func_file_conv,
|
||||
# since the user would need to supply preconverted file names to
|
||||
# binutils ar, at least for MinGW.
|
||||
func_at_file ()
|
||||
{
|
||||
operation=$2
|
||||
archive=$3
|
||||
at_file_contents=`cat "$1"`
|
||||
eval set x "$at_file_contents"
|
||||
shift
|
||||
|
||||
for member
|
||||
do
|
||||
$AR -NOLOGO $operation:"$member" "$archive" || exit $?
|
||||
done
|
||||
}
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
func_error "no command. Try '$0 --help' for more information."
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<EOF
|
||||
Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...]
|
||||
|
||||
Members may be specified in a file named with @FILE.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "$me, version $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
if test $# -lt 3; then
|
||||
func_error "you must specify a program, an action and an archive"
|
||||
fi
|
||||
|
||||
AR=$1
|
||||
shift
|
||||
while :
|
||||
do
|
||||
if test $# -lt 2; then
|
||||
func_error "you must specify a program, an action and an archive"
|
||||
fi
|
||||
case $1 in
|
||||
-lib | -LIB \
|
||||
| -ltcg | -LTCG \
|
||||
| -machine* | -MACHINE* \
|
||||
| -subsystem* | -SUBSYSTEM* \
|
||||
| -verbose | -VERBOSE \
|
||||
| -wx* | -WX* )
|
||||
AR="$AR $1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
action=$1
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
orig_archive=$1
|
||||
shift
|
||||
func_file_conv "$orig_archive"
|
||||
archive=$file
|
||||
|
||||
# strip leading dash in $action
|
||||
action=${action#-}
|
||||
|
||||
delete=
|
||||
extract=
|
||||
list=
|
||||
quick=
|
||||
replace=
|
||||
index=
|
||||
create=
|
||||
|
||||
while test -n "$action"
|
||||
do
|
||||
case $action in
|
||||
d*) delete=yes ;;
|
||||
x*) extract=yes ;;
|
||||
t*) list=yes ;;
|
||||
q*) quick=yes ;;
|
||||
r*) replace=yes ;;
|
||||
s*) index=yes ;;
|
||||
S*) ;; # the index is always updated implicitly
|
||||
c*) create=yes ;;
|
||||
u*) ;; # TODO: don't ignore the update modifier
|
||||
v*) ;; # TODO: don't ignore the verbose modifier
|
||||
*)
|
||||
func_error "unknown action specified"
|
||||
;;
|
||||
esac
|
||||
action=${action#?}
|
||||
done
|
||||
|
||||
case $delete$extract$list$quick$replace,$index in
|
||||
yes,* | ,yes)
|
||||
;;
|
||||
yesyes*)
|
||||
func_error "more than one action specified"
|
||||
;;
|
||||
*)
|
||||
func_error "no action specified"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -n "$delete"; then
|
||||
if test ! -f "$orig_archive"; then
|
||||
func_error "archive not found"
|
||||
fi
|
||||
for member
|
||||
do
|
||||
case $1 in
|
||||
@*)
|
||||
func_at_file "${1#@}" -REMOVE "$archive"
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$1"
|
||||
$AR -NOLOGO -REMOVE:"$file" "$archive" || exit $?
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
elif test -n "$extract"; then
|
||||
if test ! -f "$orig_archive"; then
|
||||
func_error "archive not found"
|
||||
fi
|
||||
if test $# -gt 0; then
|
||||
for member
|
||||
do
|
||||
case $1 in
|
||||
@*)
|
||||
func_at_file "${1#@}" -EXTRACT "$archive"
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$1"
|
||||
$AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $?
|
||||
;;
|
||||
esac
|
||||
done
|
||||
else
|
||||
$AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member
|
||||
do
|
||||
$AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
|
||||
done
|
||||
fi
|
||||
|
||||
elif test -n "$quick$replace"; then
|
||||
if test ! -f "$orig_archive"; then
|
||||
if test -z "$create"; then
|
||||
echo "$me: creating $orig_archive"
|
||||
fi
|
||||
orig_archive=
|
||||
else
|
||||
orig_archive=$archive
|
||||
fi
|
||||
|
||||
for member
|
||||
do
|
||||
case $1 in
|
||||
@*)
|
||||
func_file_conv "${1#@}"
|
||||
set x "$@" "@$file"
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$1"
|
||||
set x "$@" "$file"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
shift
|
||||
done
|
||||
|
||||
if test -n "$orig_archive"; then
|
||||
$AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $?
|
||||
else
|
||||
$AR -NOLOGO -OUT:"$archive" "$@" || exit $?
|
||||
fi
|
||||
|
||||
elif test -n "$list"; then
|
||||
if test ! -f "$orig_archive"; then
|
||||
func_error "archive not found"
|
||||
fi
|
||||
$AR -NOLOGO -LIST "$archive" || exit $?
|
||||
fi
|
||||
46
build.sh
Normal file
46
build.sh
Normal file
@@ -0,0 +1,46 @@
|
||||
#!/bin/sh
|
||||
#autoreconf --install
|
||||
|
||||
# Thanks, https://github.com/raywill/automake
|
||||
|
||||
export AUTOM4TE="autom4te"
|
||||
export AUTOCONF="autoconf"
|
||||
|
||||
# On OSX, it's glibtoolize
|
||||
LIBTOOLIZE=$(which libtoolize)
|
||||
if [ "$LIBTOOLIZE" = "" ]; then
|
||||
LIBTOOLIZE=$(which glibtoolize)
|
||||
fi
|
||||
if [ "$LIBTOOLIZE" = "" ]; then
|
||||
echo "CANNOT CONTINUE! MISSING (G)LIBTOOLIZE! Install libtool!" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
case "x$1" in
|
||||
xinit)
|
||||
[ -d m4 ] || mkdir m4
|
||||
set -x
|
||||
autoheader
|
||||
aclocal
|
||||
$LIBTOOLIZE --force --copy --automake
|
||||
autoconf --force
|
||||
automake --foreign --copy --add-missing -Woverride
|
||||
;;
|
||||
xclean)
|
||||
echo 'cleaning...'
|
||||
make distclean >/dev/null 2>&1
|
||||
rm -rf autom4te.cache
|
||||
for fn in aclocal.m4 configure config.guess config.sub depcomp install-sh \
|
||||
ltmain.sh libtool missing mkinstalldirs config.log config.status Makefile; do
|
||||
rm -f $fn
|
||||
done
|
||||
|
||||
find . -name Makefile.in -exec rm -f {} \;
|
||||
find . -name Makefile -exec rm -f {} \;
|
||||
find . -name .deps -prune -exec rm -rf {} \;
|
||||
echo 'done'
|
||||
;;
|
||||
*)
|
||||
./configure
|
||||
;;
|
||||
esac
|
||||
62
configure.ac
Normal file
62
configure.ac
Normal file
@@ -0,0 +1,62 @@
|
||||
# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info
|
||||
m4_define([lft_major_version], [0])
|
||||
m4_define([lft_minor_version], [9])
|
||||
m4_define([lft_micro_version], [8])
|
||||
m4_define([libfaketime_version],
|
||||
[lft_major_version.lft_minor_version.lft_micro_version])
|
||||
|
||||
AC_PREREQ([2.68])
|
||||
AC_INIT([libfaketime], [libfaketime_version])
|
||||
AC_SUBST([LIBTOOL_DEPS])
|
||||
#AC_CONFIG_MACRO_DIRS([m4])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
|
||||
AM_CONDITIONAL(MACOS, test `uname` = "Darwin")
|
||||
AM_CONDITIONAL(SOLARIS, test `uname` = "SunOS")
|
||||
|
||||
eval PREFIX=`test "$prefix" = NONE && prefix=$ac_default_prefix; eval echo "${prefix}"`
|
||||
eval LIBPREFIX="$PREFIX/lib"
|
||||
LIBFAKETIME_MAJOR_VERSION=lft_major_version
|
||||
AC_SUBST(PREFIX)
|
||||
AC_SUBST(LIBPREFIX)
|
||||
AC_SUBST(LIBVERSION)
|
||||
AC_DEFINE_UNQUOTED(PREFIX, "$PREFIX", [The install prefix for the package])
|
||||
AC_DEFINE_UNQUOTED(LIBPREFIX, "$LIBPREFIX", [The install prefix for libraries])
|
||||
AC_DEFINE(LIBVERSION, ["lft_major_version"], [The library version number])
|
||||
|
||||
AC_CONFIG_SRCDIR([src])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
# libtool versioning
|
||||
LIBFAKETIME_VERSION=libfaketime_version
|
||||
AC_SUBST(LIBFAKETIME_VERSION)
|
||||
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AM_PROG_AR
|
||||
|
||||
# Checks for libraries.
|
||||
AC_CHECK_LIB([c], [timespecadd], [timespecmul])
|
||||
|
||||
## FORESHADOWING...
|
||||
## AC_CHECK_LIB([cunit], [CU_assertImplementation])
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([stdlib.h sys/param.h unistd.h stdbool.h time.h netinet/in.h math.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_INLINE
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_SSIZE_T
|
||||
AC_TYPE_UINT32_T
|
||||
|
||||
# Checks for library functions.
|
||||
AC_FUNC_MALLOC
|
||||
AC_FUNC_REALLOC
|
||||
AC_CHECK_FUNCS([memset])
|
||||
|
||||
LT_INIT
|
||||
AC_CONFIG_FILES([Makefile src/Makefile test/Makefile man/Makefile])
|
||||
AC_OUTPUT
|
||||
14
man/Makefile
14
man/Makefile
@@ -1,14 +0,0 @@
|
||||
INSTALL ?= install
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
|
||||
all:
|
||||
|
||||
install:
|
||||
$(INSTALL) -Dm0644 faketime.1 "${DESTDIR}${PREFIX}/share/man/man1/faketime.1"
|
||||
gzip -f "${DESTDIR}${PREFIX}/share/man/man1/faketime.1"
|
||||
|
||||
uninstall:
|
||||
rm -f "${DESTDIR}${PREFIX}/share/man/man1/faketime.1.gz"
|
||||
|
||||
.PHONY: all install uninstall
|
||||
@@ -1,15 +0,0 @@
|
||||
INSTALL ?= install
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
|
||||
all:
|
||||
|
||||
install:
|
||||
$(INSTALL) -dm0755 "${DESTDIR}${PREFIX}/share/man/man1"
|
||||
$(INSTALL) -m0644 faketime.1 "${DESTDIR}${PREFIX}/share/man/man1/faketime.1"
|
||||
gzip -f "${DESTDIR}${PREFIX}/share/man/man1/faketime.1"
|
||||
|
||||
uninstall:
|
||||
rm -f "${DESTDIR}${PREFIX}/share/man/man1/faketime.1.gz"
|
||||
|
||||
.PHONY: all install uninstall
|
||||
18
man/Makefile.am
Normal file
18
man/Makefile.am
Normal file
@@ -0,0 +1,18 @@
|
||||
ACLOCAL_AMFLAGS=-I m4
|
||||
|
||||
dist_man_MANS = faketime.1
|
||||
|
||||
# INSTALL ?= install
|
||||
#
|
||||
# PREFIX ?= /usr/local
|
||||
#
|
||||
# all:
|
||||
#
|
||||
# install:
|
||||
# $(INSTALL) -Dm0644 faketime.1 "${DESTDIR}${PREFIX}/share/man/man1/faketime.1"
|
||||
# gzip -f "${DESTDIR}${PREFIX}/share/man/man1/faketime.1"
|
||||
#
|
||||
# uninstall:
|
||||
# rm -f "${DESTDIR}${PREFIX}/share/man/man1/faketime.1.gz"
|
||||
#
|
||||
# .PHONY: all install uninstall
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH FAKETIME "1" "February 2021" "faketime 0.9.9" wolfcw
|
||||
.TH FAKETIME "1" "August 2019" "faketime 0.9.8" 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-2021 by the libfaketime authors.
|
||||
Copyright \(co 2003-2013 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
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
# * Compilation Defines:
|
||||
#
|
||||
# FAKE_STAT
|
||||
# - Enables time faking also for files' timestamps.
|
||||
#
|
||||
# NO_ATFILE
|
||||
# - Disables support for the fstatat() group of functions
|
||||
#
|
||||
# PTHREAD
|
||||
# - Define this to enable multithreading support.
|
||||
#
|
||||
# PTHREAD_SINGLETHREADED_TIME
|
||||
# - Define this if you want to single-thread time() ... there ARE
|
||||
# possible caching side-effects in a multithreaded environment
|
||||
# without this, but the performance impact may require you to
|
||||
# try it unsynchronized.
|
||||
#
|
||||
# FAKE_SLEEP
|
||||
# - Also intercept sleep(), nanosleep(), usleep(), alarm(), [p]poll()
|
||||
#
|
||||
# * Compilation addition: second libMT target added for building the pthread-
|
||||
# enabled library as a separate library
|
||||
#
|
||||
# * Compilation switch change: previous versions compiled using '-nostartfiles'
|
||||
# This is no longer the case since there is a 'startup' constructor for the library
|
||||
# which is used to activate the start-at times when specified. This also initializes
|
||||
# the dynamic disabling of the FAKE_STAT calls.
|
||||
#
|
||||
# By default, libfaketime will be compiled for your system's default architecture.
|
||||
# To build for a different architecture, add -arch flags to CFLAGS and LDFLAGS.
|
||||
#
|
||||
# default to clang to support thread local variables
|
||||
CC ?= clang
|
||||
INSTALL ?= install
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
|
||||
CFLAGS += -DFAKE_SLEEP -DFAKE_INTERNAL_CALLS -DPREFIX='"'${PREFIX}'"' $(FAKETIME_COMPILE_CFLAGS)
|
||||
LIB_LDFLAGS += -dynamiclib -current_version 0.9.9 -compatibility_version 0.7
|
||||
|
||||
SONAME = 1
|
||||
LIBS = libfaketime.${SONAME}.dylib
|
||||
BINS = faketime
|
||||
|
||||
all: ${LIBS} ${BINS}
|
||||
|
||||
libfaketime.${SONAME}.dylib: libfaketime.c
|
||||
${CC} -o $@ ${CFLAGS} ${LDFLAGS} ${LIB_LDFLAGS} -install_name ${PREFIX}/lib/faketime/$@ $<
|
||||
|
||||
faketime: faketime.c
|
||||
${CC} -o $@ ${CFLAGS} ${LDFLAGS} $<
|
||||
|
||||
clean:
|
||||
@rm -f ${OBJ} ${LIBS} ${BINS}
|
||||
|
||||
distclean: clean
|
||||
@echo
|
||||
|
||||
install: ${LIBS} ${BINS}
|
||||
@echo
|
||||
@echo "Copying the faketime libraries to ${DESTDIR}${PREFIX}/lib/faketime and the faketime wrapper script to ${DESTDIR}${PREFIX}/bin ..."
|
||||
$(INSTALL) -dm0755 "${DESTDIR}${PREFIX}/lib/faketime/"
|
||||
$(INSTALL) -m0644 ${LIBS} "${DESTDIR}${PREFIX}/lib/faketime/"
|
||||
$(INSTALL) -dm0755 "${DESTDIR}${PREFIX}/bin"
|
||||
$(INSTALL) -m0755 faketime "${DESTDIR}${PREFIX}/bin/faketime"
|
||||
|
||||
uninstall:
|
||||
for f in ${LIBS}; do rm -f "${DESTDIR}${PREFIX}/lib/faketime/$$f"; done
|
||||
rmdir "${DESTDIR}${PREFIX}/lib/faketime"
|
||||
rm -f "${DESTDIR}${PREFIX}/bin/faketime"
|
||||
|
||||
.PHONY: all clean distclean install uninstall
|
||||
39
src/Makefile.am
Normal file
39
src/Makefile.am
Normal file
@@ -0,0 +1,39 @@
|
||||
ACLOCAL_AMFLAGS=-I m4
|
||||
LIBTOOL_DEPS = @LIBTOOL_DEPS@
|
||||
LIBOBJDIR = "."
|
||||
libtool: $(LIBTOOL_DEPS)
|
||||
$(SHELL) ./config.status libtool
|
||||
|
||||
AM_CFLAGS =-DFAKE_SLEEP -DFAKE_INTERNAL_CALLS
|
||||
|
||||
AM_LDFLAGS =
|
||||
|
||||
if SOLARIS
|
||||
AM_CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=600
|
||||
AM_LDFLAGS += -Wl,--version-script=@srcdir@/libfaketime.map
|
||||
endif
|
||||
if !MACOS
|
||||
AM_CFLAGS += -std=gnu99 -Wall -Wextra -Werror -DFAKE_STAT -DFAKE_PTHREAD -DFAKE_TIMERS -DFAKE_INTERNAL_CALLS -fPIC -Wno-nonnull-compare
|
||||
endif
|
||||
|
||||
LTCFLAGS=""
|
||||
|
||||
EXTRA_DIST=libfaketime.map
|
||||
lib_LTLIBRARIES = libfaketime.la libfaketimeMT.la
|
||||
libfaketime_la_SOURCES = libfaketime.c
|
||||
libfaketimeMT_la_SOURCES = libfaketime.c
|
||||
noinst_HEADERS = faketime_common.h sunos_endian.h time_ops.h uthash.h
|
||||
|
||||
bin_PROGRAMS = faketime
|
||||
faketime_SOURCES = faketime.c
|
||||
|
||||
if MACOS
|
||||
libfaketime_la_LDFLAGS = -dynamiclib -current_version 0.9.8 -compatibility_version 0.7
|
||||
else
|
||||
libfaketime_la_LIBADD = -ldl -lm -lrt -lpthread
|
||||
libfaketime_la_LDFLAGS = -shared -Wl,--version-script=@srcdir@/libfaketime.map
|
||||
libfaketimeMT_la_LIBADD = -ldl -lm -lrt -lpthread
|
||||
libfaketimeMT_la_CFLAGS = -DPTHREAD_SINGLETHREADED_TIME
|
||||
libfaketimeMT_la_LDFLAGS = -shared -Wl,--version-script=@srcdir@/libfaketime.map -DPTHREAD_SINGLETHREADED_TIME
|
||||
faketime_LDADD = -ldl -lm -lrt -lpthread
|
||||
endif
|
||||
@@ -6,11 +6,6 @@
|
||||
# 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
|
||||
#
|
||||
@@ -38,9 +33,6 @@
|
||||
# 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
|
||||
@@ -49,7 +41,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!
|
||||
@@ -80,7 +72,7 @@ PREFIX ?= /usr/local
|
||||
LIBDIRNAME ?= /lib/faketime
|
||||
PLATFORM ?=$(shell uname)
|
||||
|
||||
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)
|
||||
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)
|
||||
ifeq ($(PLATFORM),SunOS)
|
||||
CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=600
|
||||
endif
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* libfaketime wrapper command
|
||||
*
|
||||
* This file is part of libfaketime, version 0.9.9
|
||||
* This file is part of libfaketime, version 0.9.8
|
||||
*
|
||||
* 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
|
||||
@@ -47,8 +47,9 @@
|
||||
#include <semaphore.h>
|
||||
|
||||
#include "faketime_common.h"
|
||||
#include "config.h"
|
||||
|
||||
const char version[] = "0.9.9";
|
||||
const char version[] = VERSION;
|
||||
|
||||
#ifdef __APPLE__
|
||||
static const char *date_cmd = "gdate";
|
||||
@@ -93,11 +94,11 @@ static void cleanup_shobjs()
|
||||
{
|
||||
if (-1 == sem_unlink(sem_name))
|
||||
{
|
||||
perror("faketime: sem_unlink");
|
||||
perror("sem_unlink");
|
||||
}
|
||||
if (-1 == shm_unlink(shm_name))
|
||||
{
|
||||
perror("faketime: shm_unlink");
|
||||
perror("shm_unlink");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +172,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("faketime: Running (g)date failed");
|
||||
perror("Running (g)date failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
@@ -223,7 +224,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("faketime: sem_open");
|
||||
perror("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 +232,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("faketime: shm_open");
|
||||
perror("shm_open");
|
||||
if (-1 == sem_unlink(argv[2]))
|
||||
{
|
||||
perror("faketime: sem_unlink");
|
||||
perror("sem_unlink");
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -242,7 +243,7 @@ int main (int argc, char **argv)
|
||||
/* set shm size */
|
||||
if (-1 == ftruncate(shm_fd, sizeof(uint64_t)))
|
||||
{
|
||||
perror("faketime: ftruncate");
|
||||
perror("ftruncate");
|
||||
cleanup_shobjs();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -251,14 +252,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("faketime: mmap");
|
||||
perror("mmap");
|
||||
cleanup_shobjs();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (sem_wait(sem) == -1)
|
||||
{
|
||||
perror("faketime: sem_wait");
|
||||
perror("sem_wait");
|
||||
cleanup_shobjs();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -275,14 +276,14 @@ int main (int argc, char **argv)
|
||||
|
||||
if (-1 == munmap(ft_shared, (sizeof(struct ft_shared_s))))
|
||||
{
|
||||
perror("faketime: munmap");
|
||||
perror("munmap");
|
||||
cleanup_shobjs();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (sem_post(sem) == -1)
|
||||
{
|
||||
perror("faketime: semop");
|
||||
perror("semop");
|
||||
cleanup_shobjs();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -295,19 +296,21 @@ int main (int argc, char **argv)
|
||||
{
|
||||
char *ftpl_path;
|
||||
#ifdef __APPLE__
|
||||
ftpl_path = PREFIX "/libfaketime.1.dylib";
|
||||
FILE *check;
|
||||
check = fopen(ftpl_path, "ro");
|
||||
if (check == NULL)
|
||||
{
|
||||
ftpl_path = PREFIX "/lib/faketime/libfaketime.1.dylib";
|
||||
if (!getenv("DYLD_INSERT_LIBRARIES") && !getenv("DYLD_FORCE_FLAT_NAMESPACE")) {
|
||||
ftpl_path = LIBPREFIX "/libfaketime." LIBVERSION ".dylib";
|
||||
FILE *check;
|
||||
check = fopen(ftpl_path, "ro");
|
||||
if (check == NULL)
|
||||
{
|
||||
ftpl_path = PREFIX "/lib/faketime/libfaketime." LIBVERSION ".dylib";
|
||||
}
|
||||
else
|
||||
{
|
||||
fclose(check);
|
||||
}
|
||||
setenv("DYLD_INSERT_LIBRARIES", ftpl_path, true);
|
||||
setenv("DYLD_FORCE_FLAT_NAMESPACE", "1", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
fclose(check);
|
||||
}
|
||||
setenv("DYLD_INSERT_LIBRARIES", ftpl_path, true);
|
||||
setenv("DYLD_FORCE_FLAT_NAMESPACE", "1", true);
|
||||
#else
|
||||
{
|
||||
char *ld_preload_new, *ld_preload = getenv("LD_PRELOAD");
|
||||
@@ -318,17 +321,17 @@ int main (int argc, char **argv)
|
||||
* on MultiArch platforms, such as Debian, we put a literal $LIB into LD_PRELOAD.
|
||||
*/
|
||||
#ifndef MULTI_ARCH
|
||||
ftpl_path = PREFIX LIBDIRNAME "/libfaketimeMT.so.1";
|
||||
ftpl_path = LIBPREFIX "/libfaketimeMT.so." LIBVERSION;
|
||||
#else
|
||||
ftpl_path = PREFIX "/$LIB/faketime/libfaketimeMT.so.1";
|
||||
ftpl_path = PREFIX "/$LIB/faketime/libfaketimeMT.so." LIBVERSION;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef MULTI_ARCH
|
||||
ftpl_path = PREFIX LIBDIRNAME "/libfaketime.so.1";
|
||||
ftpl_path = LIBPREFIX "/libfaketime.so." LIBVERSION;
|
||||
#else
|
||||
ftpl_path = PREFIX "/$LIB/faketime/libfaketime.so.1";
|
||||
ftpl_path = PREFIX "/$LIB/faketime/libfaketime.so." LIBVERSION;
|
||||
#endif
|
||||
}
|
||||
len = ((ld_preload)?strlen(ld_preload) + 1: 0) + 1 + strlen(ftpl_path);
|
||||
@@ -347,7 +350,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("faketime: Running specified command failed");
|
||||
perror("Running specified command failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,4 +58,28 @@ struct ft_shared_s
|
||||
#include <mach/mach_port.h>
|
||||
#endif
|
||||
|
||||
#ifdef FAKE_SLEEP
|
||||
#include <time.h>
|
||||
#include <poll.h>
|
||||
#include <sys/types.h>
|
||||
#include <semaphore.h>
|
||||
/*
|
||||
* Fake sleep prototypes!
|
||||
*/
|
||||
struct pollfd;
|
||||
|
||||
int nanosleep(const struct timespec *req, struct timespec *rem);
|
||||
int usleep(useconds_t usec);
|
||||
unsigned int sleep(unsigned int seconds);
|
||||
unsigned int alarm(unsigned int seconds);
|
||||
int ppoll(struct pollfd *fds, nfds_t nfds,
|
||||
const struct timespec *timeout_ts, const sigset_t *sigmask);
|
||||
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
|
||||
int select(int nfds, fd_set *readfds,
|
||||
fd_set *writefds,
|
||||
fd_set *errorfds,
|
||||
struct timeval *timeout);
|
||||
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
|
||||
#endif /* FAKE_SLEEP */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of libfaketime, version 0.9.9
|
||||
* This file is part of libfaketime, version 0.9.8
|
||||
*
|
||||
* 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
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <netinet/in.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "uthash.h"
|
||||
|
||||
#include "time_ops.h"
|
||||
@@ -111,10 +112,6 @@ 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 */
|
||||
@@ -122,10 +119,6 @@ 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
|
||||
@@ -219,12 +212,6 @@ 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;
|
||||
@@ -614,15 +601,8 @@ static void next_time(struct timespec *tp, struct timespec *ticklen)
|
||||
/* lock */
|
||||
if (sem_wait(shared_sem) == -1)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
{
|
||||
return next_time(tp, ticklen);
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("libfaketime: In next_time(), sem_wait failed");
|
||||
exit(1);
|
||||
}
|
||||
perror("libfaketime: In next_time(), sem_wait failed");
|
||||
exit(1);
|
||||
}
|
||||
/* calculate and update elapsed time */
|
||||
timespecmul(ticklen, ft_shared->ticks, &inc);
|
||||
@@ -658,15 +638,8 @@ static void save_time(struct timespec *tp)
|
||||
/* lock */
|
||||
if (sem_wait(shared_sem) == -1)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
{
|
||||
return save_time(tp);
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("libfaketime: In save_time(), sem_wait failed");
|
||||
exit(1);
|
||||
}
|
||||
perror("libfaketime: In save_time(), sem_wait failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
lseek(outfile, 0, SEEK_END);
|
||||
@@ -703,15 +676,8 @@ static bool load_time(struct timespec *tp)
|
||||
/* lock */
|
||||
if (sem_wait(shared_sem) == -1)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
{
|
||||
return load_time(tp);
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("libfaketime: In load_time(), sem_wait failed");
|
||||
exit(1);
|
||||
}
|
||||
perror("libfaketime: In load_time(), sem_wait failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((sizeof(stss[0]) * (ft_shared->file_idx + 1)) > infile_size)
|
||||
@@ -771,7 +737,6 @@ 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()
|
||||
@@ -780,15 +745,8 @@ void lock_for_stat()
|
||||
{
|
||||
if (sem_wait(shared_sem) == -1)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
{
|
||||
return lock_for_stat();
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("libfaketime: In lock_for_stat(), sem_wait failed");
|
||||
exit(1);
|
||||
}
|
||||
perror("libfaketime: In lock_for_stat(), sem_wait failed");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
user_per_tick_inc_set_backup = user_per_tick_inc_set;
|
||||
@@ -1130,21 +1088,14 @@ int utime(const char *filename, const struct utimbuf *times)
|
||||
|
||||
int result;
|
||||
struct utimbuf ntbuf;
|
||||
if (fake_utime_disabled)
|
||||
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 (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;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1164,105 +1115,17 @@ int utimes(const char *filename, const struct timeval times[2])
|
||||
|
||||
int result;
|
||||
struct timeval tn[2];
|
||||
if (fake_utime_disabled)
|
||||
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 (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 */
|
||||
return -1;
|
||||
}
|
||||
|
||||
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
|
||||
@@ -2411,8 +2274,6 @@ 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");
|
||||
@@ -2448,11 +2309,6 @@ 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__
|
||||
@@ -2524,22 +2380,6 @@ 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)
|
||||
{
|
||||
@@ -2848,9 +2688,6 @@ 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;
|
||||
@@ -2867,8 +2704,11 @@ 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
|
||||
volatile int ret = INT_MAX;
|
||||
int ret = INT_MAX;
|
||||
|
||||
#ifdef PTHREAD_SINGLETHREADED_TIME
|
||||
static pthread_mutex_t time_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
@@ -3566,46 +3406,9 @@ 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;
|
||||
}
|
||||
|
||||
@@ -3654,41 +3457,6 @@ 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
|
||||
*
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
CC = gcc
|
||||
|
||||
CFLAGS = -std=gnu99 -Wall -DFAKE_STAT -Werror -Wextra $(FAKETIME_COMPILE_CFLAGS)
|
||||
LDFLAGS = -lrt -lpthread
|
||||
|
||||
SRC = timetest.c
|
||||
OBJ = ${SRC:.c=.o}
|
||||
|
||||
all: timetest test
|
||||
|
||||
.c.o:
|
||||
${CC} -c ${CFLAGS} $<
|
||||
|
||||
timetest: ${OBJ}
|
||||
${CC} -o $@ ${OBJ} ${LDFLAGS}
|
||||
|
||||
test: timetest functest
|
||||
@echo
|
||||
@./test.sh
|
||||
|
||||
# run functional tests
|
||||
functest:
|
||||
./testframe.sh functests
|
||||
|
||||
getrandom_test: getrandom_test.c
|
||||
${CC} -o $@ ${CFLAGS} $<
|
||||
|
||||
randomtest: getrandom_test
|
||||
./randomtest.sh
|
||||
|
||||
clean:
|
||||
@rm -f ${OBJ} timetest getrandom_test
|
||||
|
||||
distclean: clean
|
||||
@echo
|
||||
|
||||
.PHONY: all test clean distclean
|
||||
@@ -1,30 +0,0 @@
|
||||
CC ?= clang
|
||||
|
||||
CFLAGS += -std=gnu99 -Wall -DFAKE_STAT $(FAKETIME_COMPILE_CFLAGS)
|
||||
|
||||
SRC = timetest.c
|
||||
OBJ = ${SRC:.c=.o}
|
||||
|
||||
all: timetest test
|
||||
|
||||
.c.o:
|
||||
${CC} -c ${CFLAGS} $<
|
||||
|
||||
timetest: ${OBJ}
|
||||
${CC} -o $@ ${OBJ} ${LDFLAGS}
|
||||
|
||||
test: timetest functest
|
||||
@echo
|
||||
@./test_OSX.sh
|
||||
|
||||
# run functional tests
|
||||
functest:
|
||||
./testframe.sh functests
|
||||
|
||||
clean:
|
||||
@rm -f ${OBJ} timetest
|
||||
|
||||
distclean: clean
|
||||
@echo
|
||||
|
||||
.PHONY: all test clean distclean
|
||||
29
test/Makefile.am
Normal file
29
test/Makefile.am
Normal file
@@ -0,0 +1,29 @@
|
||||
AM_CPPFLAGS =-DFAKE_SLEEP -DFAKE_INTERNAL_CALLS -I@top_srcdir@/src
|
||||
|
||||
AM_CFLAGS =
|
||||
AM_LDFLAGS =
|
||||
|
||||
# functests.sh fail for me, test.sh hangs for me.
|
||||
# TESTS = test.sh functests.sh
|
||||
check_PROGRAMS = timetest
|
||||
timetest_SOURCES = timetest.c
|
||||
check_SCRIPTS = functests.sh testframe.sh test.sh
|
||||
EXTRA_DIST = $(check_SCRIPTS) \
|
||||
functests/common.inc \
|
||||
functests/dont_test_false.sh \
|
||||
functests/test_exclude_mono.sh \
|
||||
functests/test_null.sh \
|
||||
functests/test_true.sh \
|
||||
functests/test_walkone.sh
|
||||
|
||||
if SOLARIS
|
||||
AM_CPPFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=600
|
||||
AM_LDFLAGS += -Wl,--version-script=libfaketime.map
|
||||
endif
|
||||
if !MACOS
|
||||
AM_CPPFLAGS += -DFAKE_STAT -DFAKE_PTHREAD -DFAKE_TIMERS -DFAKE_INTERNAL_CALLS
|
||||
AM_CFLAGS += -std=gnu99 -Wall -Wextra -Werror -fPIC -Wno-nonnull-compare
|
||||
timetest_LDADD = -ldl -lm -lrt -lpthread
|
||||
endif
|
||||
|
||||
|
||||
7
test/functests.sh
Executable file
7
test/functests.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
[ "${srcdir}" ] || srcdir=.
|
||||
|
||||
# run functional tests
|
||||
# cd "${srcdir}/"
|
||||
${srcdir}/testframe.sh ${srcdir}/functests
|
||||
@@ -1,5 +1,8 @@
|
||||
# libfaketime-specific common support routines for tests
|
||||
|
||||
LIB_BUILD_PATH="../src/$(grep 'LT_OBJDIR' ../config.h | cut -d'"' -f2)"
|
||||
LIBFAKETIME_LA=$(find "$LIB_BUILD_PATH" | grep 'libfaketime\.\(dylib\|so\)$')
|
||||
|
||||
# say which *_fakecmd wrapper to use
|
||||
platform()
|
||||
{
|
||||
@@ -19,7 +22,7 @@ platform()
|
||||
mac_fakecmd()
|
||||
{
|
||||
typeset timestring="$1"; shift
|
||||
typeset fakelib=../src/libfaketime.1.dylib
|
||||
typeset fakelib="$LIBFAKETIME_LA"
|
||||
export DYLD_INSERT_LIBRARIES=$fakelib
|
||||
export DYLD_FORCE_FLAT_NAMESPACE=1
|
||||
FAKETIME="$timestring" \
|
||||
@@ -29,7 +32,7 @@ mac_fakecmd()
|
||||
sunos_fakecmd()
|
||||
{
|
||||
typeset timestring="$1"; shift
|
||||
typeset fakelib=../src/libfaketime.so.1
|
||||
typeset fakelib="$LIBFAKETIME_LA"
|
||||
export LD_PRELOAD=$fakelib
|
||||
FAKETIME="$timestring" \
|
||||
"$@"
|
||||
@@ -39,8 +42,7 @@ sunos_fakecmd()
|
||||
linuxlike_fakecmd()
|
||||
{
|
||||
typeset timestring="$1"; shift
|
||||
FTPL="${FAKETIME_TESTLIB:-../src/libfaketime.so.1}"
|
||||
typeset fakelib="$FTPL"
|
||||
typeset fakelib="$LIBFAKETIME_LA"
|
||||
export LD_PRELOAD=$fakelib
|
||||
FAKETIME="$timestring" \
|
||||
"$@"
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#!/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
|
||||
72
test/test.sh
72
test/test.sh
@@ -1,16 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
FTPL="${FAKETIME_TESTLIB:-../src/libfaketime.so.1}"
|
||||
##################################################################
|
||||
# NOTICE: #
|
||||
# When you edit this script, maintain compatibility with BASH 3. #
|
||||
# This is the version that Apple distributes. #
|
||||
##################################################################
|
||||
|
||||
LIB_BUILD_PATH="../src/$(grep 'LT_OBJDIR' ../config.h | cut -d'"' -f2)"
|
||||
LIBFAKETIME_LA=$(find "$LIB_BUILD_PATH" | grep 'libfaketime\.\(dylib\|so\)$')
|
||||
|
||||
set_libfaketime() {
|
||||
the_path="$LIBFAKETIME_LA"
|
||||
if [ "$(uname)" = "Darwin" ]; then
|
||||
export DYLD_INSERT_LIBRARIES="$the_path"
|
||||
export DYLD_FORCE_FLAT_NAMESPACE=1
|
||||
else
|
||||
export LD_PRELOAD="$the_path"
|
||||
fi
|
||||
}
|
||||
|
||||
echo $(set_libfaketime)
|
||||
|
||||
|
||||
if [ -f /etc/faketimerc ] ; then
|
||||
echo "Running the test program with your system-wide default in /etc/faketimerc"
|
||||
echo "\$ LD_PRELOAD=$FTPL ./timetest"
|
||||
LD_PRELOAD="$FTPL" ./timetest
|
||||
echo "\$ $(set_libfaketime) ./timetest"
|
||||
set_libfaketime
|
||||
./timetest
|
||||
echo
|
||||
else
|
||||
echo "Running the test program with no faked time specified"
|
||||
echo "\$ LD_PRELOAD=$FTPL ./timetest"
|
||||
LD_PRELOAD="$FTPL" ./timetest
|
||||
echo "\$ $(set_libfaketime) ./timetest"
|
||||
set_libfaketime
|
||||
./timetest
|
||||
echo
|
||||
fi
|
||||
|
||||
@@ -18,48 +40,62 @@ echo "==========================================================================
|
||||
echo
|
||||
|
||||
echo "Running the test program with absolute date 2003-01-01 10:00:05 specified"
|
||||
echo "\$ LD_PRELOAD=$FTPL FAKETIME=\"2003-01-01 10:00:05\" ./timetest"
|
||||
LD_PRELOAD="$FTPL" FAKETIME="2003-01-01 10:00:05" ./timetest
|
||||
echo "\$ $(set_libfaketime) FAKETIME=\"2003-01-01 10:00:05\" ./timetest"
|
||||
set_libfaketime
|
||||
export 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=$FTPL FAKETIME=\"@2005-03-29 14:14:14\" ./timetest"
|
||||
LD_PRELOAD="$FTPL" FAKETIME="@2005-03-29 14:14:14" ./timetest
|
||||
echo "\$ $(set_libfaketime) FAKETIME=\"@2005-03-29 14:14:14\" ./timetest"
|
||||
set_libfaketime
|
||||
export 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=$FTPL FAKETIME=\"-10d\" ./timetest"
|
||||
LD_PRELOAD="$FTPL" FAKETIME="-10d" ./timetest
|
||||
echo "$(set_libfaketime) FAKETIME=\"-10d\" ./timetest"
|
||||
set_libfaketime
|
||||
export FAKETIME="-10d"
|
||||
./timetest
|
||||
echo
|
||||
|
||||
echo "============================================================================="
|
||||
echo
|
||||
|
||||
echo "Running the test program with 10 days negative offset specified, and FAKE_STAT disabled"
|
||||
echo "\$ LD_PRELOAD=$FTPL FAKETIME=\"-10d\" NO_FAKE_STAT=1 ./timetest"
|
||||
LD_PRELOAD="$FTPL" FAKETIME="-10d" NO_FAKE_STAT=1 ./timetest
|
||||
echo "\$ $(set_libfaketime) FAKETIME=\"-10d\" NO_FAKE_STAT=1 ./timetest"
|
||||
set_libfaketime
|
||||
export FAKETIME="-10d"
|
||||
export 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=$FTPL FAKETIME=\"+10d x1\" ./timetest"
|
||||
LD_PRELOAD="$FTPL" FAKETIME="+10d x1" NO_FAKE_STAT=1 ./timetest
|
||||
echo "Running the test program with 10 days positive offset specified, and sped up 2 times"
|
||||
echo "\$ $(set_libfaketime) FAKETIME=\"+10d x2\" ./timetest"
|
||||
set_libfaketime
|
||||
export FAKETIME="+10d x2"
|
||||
export NO_FAKE_STAT=1
|
||||
./timetest
|
||||
echo
|
||||
|
||||
echo "============================================================================="
|
||||
echo
|
||||
|
||||
echo "Running the 'date' command with 15 days negative offset specified"
|
||||
echo "\$ LD_PRELOAD=$FTPL FAKETIME=\"-15d\" date"
|
||||
LD_PRELOAD="$FTPL" FAKETIME="-15d" date
|
||||
echo "\$ $(set_libfaketime) FAKETIME=\"-15d\" date"
|
||||
set_libfaketime
|
||||
export FAKETIME="-15d"
|
||||
date
|
||||
echo
|
||||
|
||||
echo "============================================================================="
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
export DYLD_FORCE_FLAT_NAMESPACE=1
|
||||
export DYLD_INSERT_LIBRARIES=../src/libfaketime.1.dylib
|
||||
|
||||
if [ -f /etc/faketimerc ] ; then
|
||||
echo "Running the test program with your system-wide default in /etc/faketimerc"
|
||||
./timetest
|
||||
echo
|
||||
else
|
||||
echo "Running the test program with no faked time specified"
|
||||
./timetest
|
||||
echo
|
||||
fi
|
||||
|
||||
echo "Running the test program with absolute date 2003-01-01 10:00:05 specified"
|
||||
echo "FAKETIME=\"2003-01-01 10:00:05\" ./timetest"
|
||||
FAKETIME="2003-01-01 10:00:05" ./timetest
|
||||
echo
|
||||
|
||||
echo "Running the test program with START date @2005-03-29 14:14:14 specified"
|
||||
echo "FAKETIME=\"@2005-03-29 14:14:14\" ./timetest"
|
||||
FAKETIME="@2005-03-29 14:14:14" ./timetest
|
||||
echo
|
||||
|
||||
echo "Running the test program with 10 days negative offset specified"
|
||||
echo "FAKETIME=\"-10d\" ./timetest"
|
||||
FAKETIME="-10d" ./timetest
|
||||
echo
|
||||
|
||||
# FAKE_STAT is disabled on macOS by default, so testing NO_FAKE_STAT is not useful
|
||||
#echo "Running the test program with 10 days negative offset specified, and FAKE_STAT disabled"
|
||||
#echo "FAKETIME=\"-10d\" NO_FAKE_STAT=1 ./timetest"
|
||||
#FAKETIME="-10d" NO_FAKE_STAT=1 ./timetest
|
||||
#echo
|
||||
|
||||
echo "Running the test program with 10 days positive offset specified, and sped up 2 times"
|
||||
echo "FAKETIME=\"+10d x2\" ./timetest"
|
||||
FAKETIME="+10d x2" NO_FAKE_STAT=1 ./timetest
|
||||
echo
|
||||
|
||||
# On more recent macOS versions, the following won't work without copying gdate
|
||||
# to a different folder beforehand. We don't do that here, and since the output
|
||||
# of these tests must be reviewed manually anyway, the timetest binary should be
|
||||
# sufficient to determine whether everything works as planned.
|
||||
|
||||
#echo "Running the 'date' command with 15 days negative offset specified"
|
||||
#echo "FAKETIME=\"-15d\" date"
|
||||
#FAKETIME="-15d" date
|
||||
#echo
|
||||
|
||||
exit 0
|
||||
@@ -6,6 +6,8 @@
|
||||
# see README.testframe.txt for details.
|
||||
#
|
||||
|
||||
testframedir="${BASH_SOURCE%/*}"
|
||||
|
||||
# echo labelled error/warning message to stderr
|
||||
report()
|
||||
{
|
||||
@@ -33,7 +35,7 @@ run_testsuite()
|
||||
# add testsuite dir to PATH for convenience
|
||||
typeset dir=$(dirname $testsuite)
|
||||
PATH=$dir:$PATH
|
||||
. testframe.inc
|
||||
. $testframedir/testframe.inc
|
||||
if [ -f $dir/common.inc ]; then
|
||||
. $dir/common.inc
|
||||
fi
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -115,6 +116,7 @@ void* pthread_test(void* args)
|
||||
}
|
||||
|
||||
#endif
|
||||
#include "faketime_common.h"
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
@@ -216,10 +218,7 @@ 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");
|
||||
@@ -246,11 +245,7 @@ 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