/* * clock-malfunction-imitation.c * * The imitations include: * - time change * - clock overflow * - clock hang * - clock reverse * - exponential growth of time * * Author: Intel A80486DX2-66 * License: Unlicense */ #include #include #include #include #include #include #define EXIT_IN 2U #define SECOND_PRECISION 1L #define TIME_BEFORE_ACCIDENT 2UL #define TEST_LABEL(s) do { \ printf("Test: %s\n", s); \ fflush(stdout); \ } while (0) #define CLOCK_FUN_BEGIN \ static unsigned ticks_before_accident = TIME_BEFORE_ACCIDENT; \ time_t y #define CLOCK_FUN_END \ if (x != NULL) \ *x = y; \ \ return y 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; size_t max = sizeof(time_t) / sizeof(int), intmax_plus_1 = (size_t) INT_MAX + 1; for (size_t i = 0; i < max; i++) y |= rand() % 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 is not normal if (time_diff != (double) SECOND_PRECISION) { printf(" -> Abnormal time flow detected!"); fflush(stdout); if (++i >= EXIT_IN) { puts("\nAborting"); fflush(stdout); break; } } putchar('\n'); fflush(stdout); // Update the previous time previous_time = current_time; usleep(SECOND_PRECISION * 1000000L); first_time_passed = true; } putchar('\n'); fflush(stdout); } int main(void) { srand(time(NULL)); TEST_LABEL("clock_change_time"); time_flow_test(&clock_change_time); TEST_LABEL("clock_exponential_growth"); time_flow_test(&clock_exponential_growth); TEST_LABEL("clock_hang"); time_flow_test(&clock_hang); TEST_LABEL("clock_overflow"); time_flow_test(&clock_overflow); TEST_LABEL("clock_reverse"); time_flow_test(&clock_reverse); return 0; }