Commit | Line | Data |
---|---|---|
45426a76 WD |
1 | /* Run a testsuite script with a timeout. */ |
2 | ||
3 | #include "rsync.h" | |
4 | ||
6e9ad2bb WD |
5 | #define DEFAULT_TIMEOUT_SECS (5*60) |
6 | #define TIMEOUT_ENV "TESTRUN_TIMEOUT" | |
45426a76 WD |
7 | |
8 | int main(int argc, char *argv[]) | |
9 | { | |
10 | pid_t pid; | |
6e9ad2bb WD |
11 | char *timeout_env; |
12 | int status, timeout_secs, slept = 0; | |
45426a76 WD |
13 | |
14 | if (argc < 2) { | |
15 | fprintf(stderr, "Usage: testrun [SHELL_OPTIONS] TESTSUITE_SCRIPT [ARGS]\n"); | |
16 | exit(1); | |
17 | } | |
18 | ||
6e9ad2bb WD |
19 | if ((timeout_env = getenv(TIMEOUT_ENV)) != NULL) |
20 | timeout_secs = atoi(timeout_env); | |
21 | else | |
22 | timeout_secs = DEFAULT_TIMEOUT_SECS; | |
23 | ||
45426a76 WD |
24 | if ((pid = fork()) < 0) { |
25 | fprintf(stderr, "TESTRUN ERROR: fork failed: %s\n", strerror(errno)); | |
26 | exit(1); | |
27 | } | |
28 | ||
29 | if (pid == 0) { | |
30 | argv[0] = "sh"; | |
31 | execvp(argv[0], argv); | |
32 | fprintf(stderr, "TESTRUN ERROR: failed to exec %s: %s\n", argv[0], strerror(errno)); | |
33 | _exit(1); | |
34 | } | |
35 | ||
36 | while (1) { | |
37 | int ret = waitpid(pid, &status, WNOHANG); | |
38 | if (ret > 0) | |
39 | break; | |
40 | if (ret < 0) { | |
41 | if (errno == EINTR) | |
42 | continue; | |
43 | fprintf(stderr, "TESTRUN ERROR: waitpid failed: %s\n", strerror(errno)); | |
44 | exit(1); | |
45 | } | |
6e9ad2bb WD |
46 | if (slept++ > timeout_secs) { |
47 | fprintf(stderr, "TESTRUN TIMEOUT: test took over %d seconds.\n", timeout_secs); | |
45426a76 WD |
48 | if (kill(pid, SIGTERM) < 0) |
49 | fprintf(stderr, "TESTRUN ERROR: failed to kill pid %ld: %s\n", (long)pid, strerror(errno)); | |
50 | else | |
51 | fprintf(stderr, "TESTRUN INFO: killed pid %ld\n", (long)pid); | |
52 | exit(1); | |
53 | } | |
54 | sleep(1); | |
55 | } | |
56 | ||
57 | if (!WIFEXITED(status)) | |
58 | exit(255); | |
59 | ||
60 | return WEXITSTATUS(status); | |
61 | } |