Allow a failure of EINVAL to mean no ACLs are available.
[rsync/rsync.git] / testrun.c
1 /* Run a testsuite script with a timeout. */
2
3 #include "rsync.h"
4
5 #define DEFAULT_TIMEOUT_SECS (5*60)
6 #define TIMEOUT_ENV "TESTRUN_TIMEOUT"
7
8  int main(int argc, char *argv[])
9 {
10         pid_t pid;
11         char *timeout_env;
12         int status, timeout_secs, slept = 0;
13
14         if (argc < 2) {
15                 fprintf(stderr, "Usage: testrun [SHELL_OPTIONS] TESTSUITE_SCRIPT [ARGS]\n");
16                 exit(1);
17         }
18
19         if ((timeout_env = getenv(TIMEOUT_ENV)) != NULL)
20                 timeout_secs = atoi(timeout_env);
21         else
22                 timeout_secs = DEFAULT_TIMEOUT_SECS;
23
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                 }
46                 if (slept++ > timeout_secs) {
47                         fprintf(stderr, "TESTRUN TIMEOUT: test took over %d seconds.\n", timeout_secs);
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 }