#define _POSIX_C_SOURCE 200809L #include #include #include #include #include #include #include #include #include #include "ts.h" #include "main_generated.c" int main(void) { struct sigaction sa = {0}; sa.sa_handler = SIG_IGN; sigaction(SIGALRM, &sa, NULL); size_t passed = 0; size_t failed = 0; size_t crashed = 0; size_t skipped = 0; for (size_t i = 0; i < NUM_TESTS; i++) { pid_t pid = fork(); if (pid < 0) { fprintf(stderr, " SKIP %s (fork failed: %s)\n", tests[i].name, strerror(errno)); skipped++; continue; } if (pid == 0) { bool ok = tests[i].func(); _exit(ok ? 0 : 1); } int status = 0; alarm(30); pid_t result = waitpid(pid, &status, 0); alarm(0); if (result < 0) { if (errno == EINTR) { kill(pid, SIGKILL); if (waitpid(pid, &status, 0) < 0) { fprintf(stderr, " CRASH %s (waitpid after SIGKILL failed: %s)\n", tests[i].name, strerror(errno)); } fprintf(stderr, " CRASH %s (timeout)\n", tests[i].name); crashed++; } else { fprintf(stderr, " CRASH %s (waitpid failed: %s)\n", tests[i].name, strerror(errno)); crashed++; } continue; } if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { printf(" PASS %s\n", tests[i].name); passed++; } else if (WIFEXITED(status)) { fprintf(stderr, " FAIL %s\n", tests[i].name); failed++; } else if (WIFSIGNALED(status)) { fprintf(stderr, " CRASH %s (signal %d)\n", tests[i].name, WTERMSIG(status)); crashed++; } else { fprintf(stderr, " CRASH %s\n", tests[i].name); crashed++; } } printf("\n--- %zu tests: %zu passed, %zu failed, %zu crashed, %zu skipped ---\n", NUM_TESTS, passed, failed, crashed, skipped); return (failed > 0 || crashed > 0) ? 1 : 0; }