fork each test so they are isolated
[libc-test] / common / main.c
1 #define _POSIX_C_SOURCE 200809L
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <signal.h>
6 #include <sys/types.h>
7 #include <sys/wait.h>
8 #include <unistd.h>
9 #include "test.h"
10
11 #define T(t) void t();
12 #include "main.h"
13 #undef T
14
15 struct test test__ = {0};
16
17 static int verbose;
18 static int count;
19 static int nfailed;
20
21 static void run(const char *n, void (*f)()) {
22         pid_t pid;
23         int status;
24
25         count++;
26         test__.failed = 0;
27         test__.name = n;
28         if (verbose)
29                 fprintf(stderr, "running %s:\n", test__.name);
30
31         pid = fork();
32         if (pid == 0) {
33                 /* run test in a child process */
34                 f();
35                 exit(test__.failed);
36         }
37
38         if (pid == -1)
39                 error("fork failed: %s\n", strerror(errno));
40         else {
41                 if (waitpid(pid, &status, 0) == -1)
42                         error("waitpid failed: %s\n", strerror(errno));
43                 else if (!WIFEXITED(status))
44                         error("abnormal exit: %s\n", WIFSIGNALED(status) ? strsignal(WTERMSIG(status)) : "(unknown)");
45                 else
46                         test__.failed = !!WEXITSTATUS(status);
47         }
48
49         if (test__.failed) {
50                 nfailed++;
51                 fprintf(stderr, "FAILED %s\n", test__.name);
52         } else if (verbose)
53                 fprintf(stderr, "PASSED %s\n", test__.name);
54 }
55
56 static int summary() {
57         fprintf(stderr, "PASS:%d FAIL:%d\n", count-nfailed, nfailed);
58         return !!nfailed;
59 }
60
61 int main() {
62 #define T(t) run(#t, t);
63 #include "main.h"
64         return summary();
65 }