2024-01-25 22:53:51 +05:30
|
|
|
/*
|
|
|
|
* clock-malfunction-imitation.c
|
|
|
|
*
|
|
|
|
* Author: Intel A80486DX2-66
|
|
|
|
* License: Creative Commons Zero 1.0 Universal
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <limits.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#define EXIT_IN 2U
|
|
|
|
#define SECOND_PRECISION 1L
|
|
|
|
#define TIME_BEFORE_ACCIDENT 2UL
|
|
|
|
|
2024-02-20 22:17:40 +05:30
|
|
|
#define TEST_LABEL(s) do { \
|
|
|
|
printf("Test: %s\n", s); \
|
|
|
|
fflush(stdout); \
|
|
|
|
} while (0)
|
2024-01-25 22:53:51 +05:30
|
|
|
|
|
|
|
#define CLOCK_FUN_BEGIN \
|
2024-02-20 22:17:40 +05:30
|
|
|
static unsigned ticks_before_accident = TIME_BEFORE_ACCIDENT; \
|
|
|
|
time_t y;
|
2024-01-25 22:53:51 +05:30
|
|
|
|
|
|
|
#define CLOCK_FUN_END \
|
2024-02-20 22:17:40 +05:30
|
|
|
if (x != NULL) \
|
|
|
|
*x = y; \
|
|
|
|
\
|
|
|
|
return y;
|
2024-01-25 22:53:51 +05:30
|
|
|
|
|
|
|
time_t clock_change_time(time_t* x);
|
|
|
|
time_t clock_exponential_growth(time_t* x);
|
|
|
|
time_t clock_hang(time_t* x);
|
|
|
|
time_t clock_overflow(time_t* x);
|
|
|
|
time_t clock_reverse(time_t* x);
|
|
|
|
void time_flow_test(time_t (*time_function)(time_t*));
|
|
|
|
|
|
|
|
time_t clock_change_time(time_t* x) {
|
|
|
|
CLOCK_FUN_BEGIN
|
|
|
|
|
|
|
|
time(&y);
|
|
|
|
|
|
|
|
if (ticks_before_accident == 0) {
|
|
|
|
y = 0;
|
|
|
|
|
2024-02-22 00:21:26 +05:30
|
|
|
size_t max = sizeof(time_t) / sizeof(int),
|
|
|
|
intmax_plus_1 = (size_t) INT_MAX + 1;
|
2024-01-25 22:53:51 +05:30
|
|
|
|
|
|
|
for (size_t i = 0; i < max; i++)
|
|
|
|
y |= (rand() & INT_MAX) * intmax_plus_1;
|
|
|
|
} else
|
|
|
|
ticks_before_accident--;
|
|
|
|
|
|
|
|
CLOCK_FUN_END
|
|
|
|
}
|
|
|
|
|
|
|
|
time_t clock_exponential_growth(time_t* x) {
|
|
|
|
CLOCK_FUN_BEGIN
|
|
|
|
|
|
|
|
static time_t counter = 1;
|
|
|
|
|
|
|
|
time(&y);
|
|
|
|
|
|
|
|
if (ticks_before_accident == 0) {
|
|
|
|
y += counter++;
|
|
|
|
counter *= counter;
|
|
|
|
} else {
|
|
|
|
ticks_before_accident--;
|
|
|
|
}
|
|
|
|
|
|
|
|
CLOCK_FUN_END
|
|
|
|
}
|
|
|
|
|
|
|
|
time_t clock_hang(time_t* x) {
|
|
|
|
CLOCK_FUN_BEGIN
|
|
|
|
|
|
|
|
static time_t last_time;
|
|
|
|
|
|
|
|
if (ticks_before_accident == 0)
|
|
|
|
y = last_time;
|
|
|
|
else {
|
|
|
|
time(&y);
|
|
|
|
last_time = y;
|
|
|
|
ticks_before_accident--;
|
|
|
|
}
|
|
|
|
|
|
|
|
CLOCK_FUN_END
|
|
|
|
}
|
|
|
|
|
|
|
|
time_t clock_overflow(time_t* x) {
|
|
|
|
CLOCK_FUN_BEGIN
|
|
|
|
|
|
|
|
time(&y);
|
|
|
|
|
|
|
|
if (ticks_before_accident == 0)
|
|
|
|
y = LONG_MAX - y;
|
|
|
|
else
|
|
|
|
ticks_before_accident--;
|
|
|
|
|
|
|
|
CLOCK_FUN_END
|
|
|
|
}
|
|
|
|
|
|
|
|
time_t clock_reverse(time_t* x) {
|
|
|
|
CLOCK_FUN_BEGIN
|
|
|
|
|
|
|
|
static time_t counter = 1, old_time;
|
|
|
|
|
|
|
|
if (ticks_before_accident == 0) {
|
|
|
|
y = old_time - counter++;
|
|
|
|
} else {
|
|
|
|
time(&y);
|
|
|
|
old_time = y;
|
|
|
|
ticks_before_accident--;
|
|
|
|
}
|
|
|
|
|
|
|
|
CLOCK_FUN_END
|
|
|
|
}
|
|
|
|
|
|
|
|
void time_flow_test(time_t (*time_function)(time_t*)) {
|
|
|
|
time_t current_time, previous_time;
|
|
|
|
double time_diff;
|
|
|
|
|
|
|
|
// Get the current time
|
|
|
|
time(¤t_time);
|
|
|
|
previous_time = current_time;
|
|
|
|
bool first_time_passed = false;
|
|
|
|
unsigned i = 0;
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
// Get the current time
|
|
|
|
time_function(¤t_time);
|
|
|
|
|
|
|
|
// Calculate the time difference in seconds
|
|
|
|
time_diff = difftime(current_time, previous_time);
|
|
|
|
if (!first_time_passed) {
|
|
|
|
time_diff = (double) SECOND_PRECISION;
|
|
|
|
first_time_passed = true;
|
|
|
|
}
|
|
|
|
printf("time difference: %f", time_diff);
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
// Check if the time difference exceeds a threshold (e.g., 1 second)
|
|
|
|
if (time_diff != (double) SECOND_PRECISION) {
|
|
|
|
printf(" -> Abnormal time flow detected!");
|
|
|
|
fflush(stdout);
|
|
|
|
if (++i >= EXIT_IN) {
|
|
|
|
printf("\nAborting\n");
|
|
|
|
fflush(stdout);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
// Update the previous time
|
|
|
|
previous_time = current_time;
|
|
|
|
|
|
|
|
usleep(SECOND_PRECISION * 1000000L);
|
|
|
|
|
|
|
|
first_time_passed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("\n");
|
|
|
|
fflush(stdout);
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(void) {
|
2024-02-21 00:48:40 +05:30
|
|
|
TEST_LABEL("clock_change_time");
|
2024-01-25 22:53:51 +05:30
|
|
|
time_flow_test(&clock_change_time);
|
|
|
|
|
2024-02-21 00:48:40 +05:30
|
|
|
TEST_LABEL("clock_exponential_growth");
|
2024-01-25 22:53:51 +05:30
|
|
|
time_flow_test(&clock_exponential_growth);
|
|
|
|
|
2024-02-21 00:48:40 +05:30
|
|
|
TEST_LABEL("clock_hang");
|
2024-01-25 22:53:51 +05:30
|
|
|
time_flow_test(&clock_hang);
|
|
|
|
|
2024-02-21 00:48:40 +05:30
|
|
|
TEST_LABEL("clock_overflow");
|
2024-01-25 22:53:51 +05:30
|
|
|
time_flow_test(&clock_overflow);
|
|
|
|
|
2024-02-21 00:48:40 +05:30
|
|
|
TEST_LABEL("clock_reverse");
|
2024-01-25 22:53:51 +05:30
|
|
|
time_flow_test(&clock_reverse);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|