diff options
Diffstat (limited to 'tests/deckard/contrib/libfaketime/test')
14 files changed, 893 insertions, 0 deletions
diff --git a/tests/deckard/contrib/libfaketime/test/Makefile b/tests/deckard/contrib/libfaketime/test/Makefile new file mode 100644 index 0000000..94d1a2e --- /dev/null +++ b/tests/deckard/contrib/libfaketime/test/Makefile @@ -0,0 +1,31 @@ +CC = gcc + +CFLAGS = -std=gnu99 -Wall -DFAKE_STAT -Werror -Wextra +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 + +clean: + @rm -f ${OBJ} timetest + +distclean: clean + @echo + +.PHONY: all test clean distclean diff --git a/tests/deckard/contrib/libfaketime/test/Makefile.OSX b/tests/deckard/contrib/libfaketime/test/Makefile.OSX new file mode 100644 index 0000000..209d19f --- /dev/null +++ b/tests/deckard/contrib/libfaketime/test/Makefile.OSX @@ -0,0 +1,30 @@ +CC ?= clang + +CFLAGS += -std=gnu99 -Wall -DFAKE_STAT + +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 diff --git a/tests/deckard/contrib/libfaketime/test/README-testframe.txt b/tests/deckard/contrib/libfaketime/test/README-testframe.txt new file mode 100644 index 0000000..d6980c3 --- /dev/null +++ b/tests/deckard/contrib/libfaketime/test/README-testframe.txt @@ -0,0 +1,39 @@ +# here's how the testframe script works. +# +# Usage for testing: +# usage: testframe.sh DIR +# testframe.sh runs each testsuite script found within DIR. +# (in the context of libfaketime, the DIR is functest.) +# exits with status 0 if all tests succeed. +# +# Interface: +# by convention, each testsuite script (within DIR) must be +# a bash script named test_*.sh. the script must define a +# function named "run". run takes no arguments. run is +# expected to call the framework-provided function +# run_testcase once for each test function. run_testcase +# uses the global vars NFAIL and NSUCC to keep track of how +# many testcases failed/succeeded. +# +# the test function is expected to call something like +# asserteq or assertneq (again, framework-provided). +# +# fine print: for each testsuite, the framework creates a +# subshell and dots in the script. also dotted in are +# testframe.inc and DIR/common.inc (if it exists). the +# testsuite script can make use of any functions defined +# in these inc files. the environment variable +# TESTSUITE_NAME is set to the filename of the testsuite +# script, for possible use in warning or info messages. +# +# see functests/test_true.sh for a simple example of +# a test suite script. +# +# Simple steps to add a new testsuite: +# 1. decide its name - eg, XXX. +# 2. choose a DIR of similar testsuites to put it in, or create a new one. +# 3. create DIR/test_XXX.sh. +# 4. write a run function and testcase functions in DIR/test_XXX.sh. +# 5. within the run function, call run_testcase for each testcase function. +# 6. within each testcase function, call assertneq or asserteq, or do +# the equivalent. diff --git a/tests/deckard/contrib/libfaketime/test/functests/common.inc b/tests/deckard/contrib/libfaketime/test/functests/common.inc new file mode 100644 index 0000000..d184ae2 --- /dev/null +++ b/tests/deckard/contrib/libfaketime/test/functests/common.inc @@ -0,0 +1,63 @@ +# libfaketime-specific common support routines for tests + +# say which *_fakecmd wrapper to use +platform() +{ + # may want to expand the pattern for linuxlike + typeset out=$(uname) + case "$out" in + *Darwin*) echo "mac" ;; + *Linux*) echo "linuxlike" ;; + GNU|GNU/kFreeBSD) echo "linuxlike" ;; + *SunOS*) echo "sunos" ;; + *) echo 1>&2 unsupported platform, uname=\"$out\" ;; + esac +} + +# run faked command on a mac +# UNTESTED +mac_fakecmd() +{ + typeset timestring="$1"; shift + typeset fakelib=../src/libfaketime.1.dylib + export DYLD_INSERT_LIBRARIES=$fakelib + export DYLD_FORCE_FLAT_NAMESPACE=1 + FAKETIME="$timestring" \ + "$@" +} + +sunos_fakecmd() +{ + typeset timestring="$1"; shift + typeset fakelib=../src/libfaketime.so.1 + export LD_PRELOAD=$fakelib + FAKETIME="$timestring" \ + "$@" +} + +# run faked command on linuxlike OS +linuxlike_fakecmd() +{ + typeset timestring="$1"; shift + typeset fakelib=../src/libfaketime.so.1 + export LD_PRELOAD=$fakelib + FAKETIME="$timestring" \ + "$@" +} + +# run a command with libfaketime using the given timestring +fakecmd() +{ + ${PLATFORM}_fakecmd "$@" +} + +# generate a sequence of numbers from a to b +range() +{ + typeset a=$1 b=$2 + typeset i=$a + while ((i <= b)); do + echo $i + ((i = i+1)) + done +} diff --git a/tests/deckard/contrib/libfaketime/test/functests/dont_test_false.sh b/tests/deckard/contrib/libfaketime/test/functests/dont_test_false.sh new file mode 100644 index 0000000..65457ef --- /dev/null +++ b/tests/deckard/contrib/libfaketime/test/functests/dont_test_false.sh @@ -0,0 +1,6 @@ +# a testsuite that will force failure - for testing purposes + +run() +{ + run_testcase false +} diff --git a/tests/deckard/contrib/libfaketime/test/functests/test_exclude_mono.sh b/tests/deckard/contrib/libfaketime/test/functests/test_exclude_mono.sh new file mode 100644 index 0000000..f68fc20 --- /dev/null +++ b/tests/deckard/contrib/libfaketime/test/functests/test_exclude_mono.sh @@ -0,0 +1,87 @@ +# Checks that setting DONT_FAKE_MONOTONIC actually prevent +# libfaketime from faking monotonic clocks. +# +# We do this by freezing time at a specific and arbitrary date with faketime, +# and making sure that if we set DONT_FAKE_MONOTONIC to 1, calling +# clock_gettime(CLOCK_MONOTONIC) returns two different values. +# +# We also make sure that if we don't set DONT_FAKE_MONOTONIC to 1, in other +# words when we use the default behavior, two subsequent calls to +# clock_gettime(CLOCK_MONOTONIC) do return different values. + +init() +{ + typeset testsuite="$1" + PLATFORM=$(platform) + if [ -z "$PLATFORM" ]; then + echo "$testsuite: unknown platform! quitting" + return 1 + fi + echo "# PLATFORM=$PLATFORM" + return 0 +} + +run() +{ + init + + run_testcase dont_fake_mono + run_testcase fake_mono +} + +get_token() +{ + string=$1 + token_index=$2 + separator=$3 + + echo $string | cut -d "$separator" -f $token_index +} + +assert_timestamps_neq() +{ + timestamps=$1 + msg=$2 + + first_timestamp=$(get_token "${timestamps}" 1 ' ') + second_timestamp=$(get_token "${timestamps}" 2 ' ') + + assertneq "${first_timestamp}" "${second_timestamp}" "${msg}" +} + +assert_timestamps_eq() +{ + timestamps=$1 + msg=$2 + + first_timestamp=$(get_token "${timestamps}" 1 ' ') + second_timestamp=$(get_token "${timestamps}" 2 ' ') + + asserteq "${first_timestamp}" "${second_timestamp}" "${msg}" +} + +get_monotonic_time() +{ + dont_fake_mono=$1; shift; + clock_id=$1; shift; + DONT_FAKE_MONOTONIC=${dont_fake_mono} fakecmd "2014-07-21 09:00:00" \ + /bin/bash -c "for i in 1 2; do \ + perl -w -MTime::HiRes=clock_gettime,${clock_id} -E \ + 'say clock_gettime(${clock_id})'; \ + sleep 1; \ + done" +} + +dont_fake_mono() +{ + timestamps=$(get_monotonic_time 1 CLOCK_MONOTONIC) + msg="When not faking monotonic time, timestamps should be different" + assert_timestamps_neq "${timestamps}" "${msg}" +} + +fake_mono() +{ + timestamps=$(get_monotonic_time 0 CLOCK_MONOTONIC) + msg="When faking monotonic, timestamps should be equal" + assert_timestamps_eq "${timestamps}" "${msg}" +} diff --git a/tests/deckard/contrib/libfaketime/test/functests/test_null.sh b/tests/deckard/contrib/libfaketime/test/functests/test_null.sh new file mode 100644 index 0000000..09e7560 --- /dev/null +++ b/tests/deckard/contrib/libfaketime/test/functests/test_null.sh @@ -0,0 +1,13 @@ +# check that the date doesn't happen to be 0. + +run() +{ + run_testcase nulltest +} + +nulltest() +{ + typeset tdate=${I2DATES[0]} + + assertneq 0 "$(date +%s)" "($tdate)" +} diff --git a/tests/deckard/contrib/libfaketime/test/functests/test_true.sh b/tests/deckard/contrib/libfaketime/test/functests/test_true.sh new file mode 100644 index 0000000..0025bcf --- /dev/null +++ b/tests/deckard/contrib/libfaketime/test/functests/test_true.sh @@ -0,0 +1,7 @@ +# test suite that always succeeds - for testing framework + +run() +{ + run_testcase true + return 0 +} diff --git a/tests/deckard/contrib/libfaketime/test/functests/test_walkone.sh b/tests/deckard/contrib/libfaketime/test/functests/test_walkone.sh new file mode 100755 index 0000000..b27df9a --- /dev/null +++ b/tests/deckard/contrib/libfaketime/test/functests/test_walkone.sh @@ -0,0 +1,67 @@ +# walking-1 test. +# sourced in from testframe.sh. +# +# this script defines a suite of functional tests +# that verifies the correct operation of libfaketime +# with the date command. + +run() +{ + init + + for i in $(range 0 30); do + run_testcase test_with_i $i + done +} + +# ----- support routines +init() +{ + typeset testsuite="$1" + PLATFORM=$(platform) + if [ -z "$PLATFORM" ]; then + echo "$testsuite: unknown platform! quitting" + return 1 + fi + echo "# PLATFORM=$PLATFORM" + return 0 +} + + +# run date cmd under faketime, print time in secs +fakedate() +{ + # + # let the time format be raw seconds since Epoch + # for both input to libfaketime, and output of the date cmd. + # + typeset fmt='%s' + export FAKETIME_FMT=$fmt + fakecmd "$1" date +$fmt +} + +# +# compute x**n. +# use only the shell, in case we need to run on machines +# without bc, dc, perl, etc. +# +pow() +{ + typeset x="$1" n="$2" + typeset r=1 + typeset i=0 + while ((i < n)); do + ((r = r*x)) + ((i++)) + done + echo $r +} + +# run a fakedate test with a given time t +test_with_i() +{ + typeset i="$1" + typeset t=$(pow 2 $i) + + asserteq $(fakedate $t) $t "(secs since Epoch)" +} diff --git a/tests/deckard/contrib/libfaketime/test/test.sh b/tests/deckard/contrib/libfaketime/test/test.sh new file mode 100755 index 0000000..630cec6 --- /dev/null +++ b/tests/deckard/contrib/libfaketime/test/test.sh @@ -0,0 +1,66 @@ +#!/bin/sh + +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 +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 +fi + +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 + +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 + +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 + +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 + +echo "=============================================================================" +echo + +echo "Running the test program with 10 days positive offset specified, and sped up 2 times" +echo "\$ LD_PRELOAD=../src/libfaketime.so.1 FAKETIME=\"+10d x2\" ./timetest" +LD_PRELOAD=../src/libfaketime.so.1 FAKETIME="+10d x2" 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 + +echo "=============================================================================" +echo "Testing finished." + +exit 0 diff --git a/tests/deckard/contrib/libfaketime/test/test_OSX.sh b/tests/deckard/contrib/libfaketime/test/test_OSX.sh new file mode 100755 index 0000000..a259275 --- /dev/null +++ b/tests/deckard/contrib/libfaketime/test/test_OSX.sh @@ -0,0 +1,46 @@ +#!/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 + +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 + +echo "Running the 'date' command with 15 days negative offset specified" +echo "FAKETIME=\"-15d\" date" +FAKETIME="-15d" date +echo + +exit 0 diff --git a/tests/deckard/contrib/libfaketime/test/testframe.inc b/tests/deckard/contrib/libfaketime/test/testframe.inc new file mode 100644 index 0000000..b5f66a3 --- /dev/null +++ b/tests/deckard/contrib/libfaketime/test/testframe.inc @@ -0,0 +1,55 @@ +# framework common functions for use in test suites and test cases + +# +# run a test and keep stats on success/failure. +# arguments: a command, possibly a shell function. +# return value: 0 on success, 1 on failure. +# side effects: increments global var NSUCC on success, NFAIL on failure. +# +run_testcase() +{ + if "$@"; then + ((NSUCC++)) + return 0 + else + ((NFAIL++)) + return 1 + fi +} + +# +# verbosely check that the test output matches the expected value. +# arguments: the test output, the expected value, and a description. +# return value: 0 on if test output equals expected value; 1 otherwise. +# side effects: prints a descriptive message. +# +asserteq() +{ + typeset out="$1" expected="$2" desc="$3" + echo -n "out=$out $desc" + if [ "$out" = "$expected" ]; then + echo " - ok" + return 0 + else + echo " expected=$expected - bad" + return 1 + fi +} + +# +# verbosely check that the test output doesn't match the reference value. +# return value: 1 on if test output equals expected value; 0 if not equal. +# side effects: prints descriptive message. +# +assertneq() +{ + typeset out="$1" ref="$2" desc="$3" + echo -n "out=$out $desc" + if [ "$out" = "$ref" ]; then + echo " ref=$ref - bad" + return 1 + else + echo " ref=$ref - ok" + return 0 + fi +} diff --git a/tests/deckard/contrib/libfaketime/test/testframe.sh b/tests/deckard/contrib/libfaketime/test/testframe.sh new file mode 100755 index 0000000..22975b6 --- /dev/null +++ b/tests/deckard/contrib/libfaketime/test/testframe.sh @@ -0,0 +1,99 @@ +#! /bin/bash +# testframe.sh DIR +# bare-bones testing framework. +# run the test suites in the given DIR; +# exit with nonzero status if any of them failed. +# see README.testframe.txt for details. +# + +# echo labelled error/warning message to stderr +report() +{ + echo $PROG: $* 1>&2 +} + +# echo OK or BAD depending on argument (0 or not) +status_word() +{ + if [ "$1" -eq 0 ]; then + echo OK + else + echo BAD + fi +} + +# run the given testsuite, return nonzero if any testcase failed. +run_testsuite() +{ + typeset testsuite="$1" + + NFAIL=0 + NSUCC=0 + + # add testsuite dir to PATH for convenience + typeset dir=$(dirname $testsuite) + PATH=$dir:$PATH + . testframe.inc + if [ -f $dir/common.inc ]; then + . $dir/common.inc + fi + . $testsuite + export TESTSUITE_NAME=$testsuite + + echo "" + echo "# Begin $testsuite" + + run + typeset runstat=$? + + echo "# $testsuite summary: $NSUCC succeeded, $NFAIL failed" + if [ $runstat -ne 0 ]; then + ((NFAIL++)) + report "error: $testsuite run exit_status=$runstat!" + fi + echo "# End $testsuite -" $(status_word $NFAIL) + [ $NFAIL -eq 0 ] +} + +# +# list all testsuite scripts in the given directories. +# a testsuite file must be a bash script whose name is of the form test_*.sh . +# +list_testsuites() +{ + for dir in "$@"; do + ls $dir/test_*.sh 2>/dev/null + done +} + +main() +{ + TS_NFAIL=0 + TS_NSUCC=0 + + echo "# Begin Test Suites in $*" + typeset testsuites=$(list_testsuites "$@") + + if [ -z "$testsuites" ]; then + report "error: no testsuites found" + exit 1 + fi + + for testsuite in $testsuites; do + if run_testsuite $testsuite; then + ((TS_NSUCC++)) + else + ((TS_NFAIL++)) + fi + done + + echo "" + echo "# Test Suites summary: $TS_NSUCC succeeded, $TS_NFAIL failed" + echo "# End Test Suites -" $(status_word $TS_NFAIL) + [ $TS_NFAIL -eq 0 ] +} + +# ----- start of mainline code +PROG=${0##*/} + +main "${@:-.}" diff --git a/tests/deckard/contrib/libfaketime/test/timetest.c b/tests/deckard/contrib/libfaketime/test/timetest.c new file mode 100644 index 0000000..4e3515c --- /dev/null +++ b/tests/deckard/contrib/libfaketime/test/timetest.c @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2003,2007 Wolfgang Hommel + * + * This file is part of the FakeTime Preload Library. + * + * The FakeTime Preload Library 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 of the + * License, or (at your option) any later version. + * + * The FakeTime Preload Library 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 the FakeTime Preload Library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <sys/time.h> +#include <sys/timeb.h> + +#ifdef FAKE_STAT +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#endif + +#ifndef __APPLE__ +#include <pthread.h> +#include <errno.h> +#include <signal.h> + +#define VERBOSE 0 + +#define SIG SIGUSR1 + +static void +handler(int sig, siginfo_t *si, void *uc) +{ + /* Note: calling printf() from a signal handler is not + strictly correct, since printf() is not async-signal-safe; + see signal(7) */ + + if ((si == NULL) || (si != uc)) + { + printf("Caught signal %d\n", sig); + } +} + +void* pthread_test(void* args) +{ + pthread_mutex_t fakeMutex = PTHREAD_MUTEX_INITIALIZER; + pthread_cond_t fakeCond = PTHREAD_COND_INITIALIZER; + + pthread_cond_t monotonic_cond; + pthread_condattr_t attr; + + struct timespec timeToWait, now; + int rt; + + args = args; // silence compiler warning about unused argument + + clock_gettime(CLOCK_REALTIME, &now); + timeToWait.tv_sec = now.tv_sec+1; + timeToWait.tv_nsec = now.tv_nsec; + + printf("pthread_cond_timedwait: CLOCK_REALTIME test\n"); + printf("(Intentionally sleeping 1 second...)\n"); + fflush(stdout); + + pthread_mutex_lock(&fakeMutex); + rt = pthread_cond_timedwait(&fakeCond, &fakeMutex, &timeToWait); + if (rt != ETIMEDOUT) + { + printf("pthread_cond_timedwait failed\n"); + exit(EXIT_FAILURE); + } + pthread_mutex_unlock(&fakeMutex); + + + pthread_condattr_init(&attr); + pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); + pthread_cond_init(&monotonic_cond, &attr); + + clock_gettime(CLOCK_MONOTONIC, &now); + timeToWait.tv_sec = now.tv_sec+1; + timeToWait.tv_nsec = now.tv_nsec; + + printf("pthread_cond_timedwait: CLOCK_MONOTONIC test\n"); + printf("(Intentionally sleeping 1 second...)\n"); + fflush(stdout); + + pthread_mutex_lock(&fakeMutex); + rt = pthread_cond_timedwait(&monotonic_cond, &fakeMutex, &timeToWait); + if (rt != ETIMEDOUT) + { + printf("pthread_cond_timedwait failed\n"); + exit(EXIT_FAILURE); + } + pthread_mutex_unlock(&fakeMutex); + + pthread_cond_destroy(&monotonic_cond); + + return NULL; +} + +#endif + +int main (int argc, char **argv) +{ + time_t now; + struct timeb tb; + struct timeval tv; +#ifndef __APPLE__ + struct timespec ts; + timer_t timerid1 = 0, timerid2; + struct sigevent sev; + struct itimerspec its; + sigset_t mask; + struct sigaction sa; +#endif +#ifdef FAKE_STAT + struct stat buf; +#endif + +#ifndef __APPLE__ + pthread_t thread; + void *ret; + + pthread_create(&thread, NULL, pthread_test, NULL); + pthread_join(thread, &ret); + + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = handler; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGUSR1, &sa, NULL) == -1) + { + perror("sigaction"); + exit(EXIT_FAILURE); + } + + /* Block timer signal temporarily */ + printf("Blocking signal %d\n", SIGUSR1); + sigemptyset(&mask); + sigaddset(&mask, SIGUSR1); + if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1) + { + perror("sigaction"); + exit(EXIT_FAILURE); + } + + /* Create the timer */ + sev.sigev_notify = SIGEV_SIGNAL; + sev.sigev_signo = SIGUSR1; + sev.sigev_value.sival_ptr = &timerid1; + if (timer_create(CLOCK_REALTIME, &sev, &timerid1) == -1) + { + perror("timer_create"); + exit(EXIT_FAILURE); + } + + /* Start timer1 */ + + /* start timer ticking after one second */ + its.it_value.tv_sec = 1; + its.it_value.tv_nsec = 0; + /* fire in every 0.3 seconds */ + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 300000000; + + if (timer_settime(timerid1, 0, &its, NULL) == -1) + { + perror("timer_settime"); + exit(EXIT_FAILURE); + } + + sev.sigev_value.sival_ptr = &timerid2; + if (timer_create(CLOCK_REALTIME, &sev, &timerid2) == -1) + { + perror("timer_create"); + exit(EXIT_FAILURE); + } + + /* Start timer2 */ + + clock_gettime(CLOCK_REALTIME, &its.it_value); + /* start timer ticking after one second */ + its.it_value.tv_sec += 3; + /* fire once */ + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 0; + + if (timer_settime(timerid2, TIMER_ABSTIME, &its, NULL) == -1) + { + perror("timer_settime"); + exit(EXIT_FAILURE); + } +#endif + + time(&now); + printf("time() : Current date and time: %s", ctime(&now)); + printf("time(NULL) : Seconds since Epoch : %u\n", (unsigned int)time(NULL)); + + ftime(&tb); + printf("ftime() : Current date and time: %s", ctime(&tb.time)); + + printf("(Intentionally sleeping 2 seconds...)\n"); + fflush(stdout); + if (argc < 3) + { + sleep(1); + usleep(1000000); + } + + gettimeofday(&tv, NULL); + printf("gettimeofday() : Current date and time: %s", ctime(&tv.tv_sec)); + +#ifndef __APPLE__ + if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) + { + perror("sigprocmask"); + exit(EXIT_FAILURE); + } + + clock_gettime(CLOCK_REALTIME, &ts); + printf("clock_gettime(): Current date and time: %s", ctime(&ts.tv_sec)); + + int timer_getoverrun_timerid1 = timer_getoverrun(timerid1); + if (timer_getoverrun_timerid1 != 3) + { + printf("timer_getoverrun(timerid1) FAILED, must be 3 but got: %d\n", timer_getoverrun_timerid1); + } + + timer_gettime(timerid1, &its); + if (VERBOSE == 1) + { + printf("timer_gettime(timerid1, &its); its = {{%ld, %ld}, {%ld, %ld}}}\n", + (long)its.it_interval.tv_sec, (long)its.it_interval.tv_nsec, + (long)its.it_value.tv_sec, (long)its.it_value.tv_nsec); + } + + int timer_getoverrun_timerid2 = timer_getoverrun(timerid2); + if (timer_getoverrun_timerid2 != 0) + { + printf("timer_getoverrun(timerid2) FAILED, must be 0 but got: %d\n", timer_getoverrun_timerid2); + } + + timer_gettime(timerid2, &its); + if (VERBOSE == 1) + { + printf("timer_gettime(timerid2, &its); its = {{%ld, %ld}, {%ld, %ld}}}\n", + (long)its.it_interval.tv_sec, (long)its.it_interval.tv_nsec, + (long)its.it_value.tv_sec, (long)its.it_value.tv_nsec); + } +#endif + +#ifdef FAKE_STAT + lstat(argv[0], &buf); + printf("stat(): mod. time of file '%s': %s", argv[0], ctime(&buf.st_mtime)); +#endif + + return 0; +} + +/* + * Editor modelines + * + * Local variables: + * c-basic-offset: 2 + * tab-width: 2 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=2 tabstop=2 expandtab: + * :indentSize=2:tabSize=2:noTabs=true: + */ + +/* eof */ |