]> Pileus Git - ~andy/linux/blob - tools/testing/selftests/powerpc/harness.c
Merge branch 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelv...
[~andy/linux] / tools / testing / selftests / powerpc / harness.c
1 /*
2  * Copyright 2013, Michael Ellerman, IBM Corp.
3  * Licensed under GPLv2.
4  */
5
6 #include <errno.h>
7 #include <signal.h>
8 #include <stdbool.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <sys/types.h>
12 #include <sys/wait.h>
13 #include <unistd.h>
14
15 #include "subunit.h"
16 #include "utils.h"
17
18 #define TIMEOUT         120
19 #define KILL_TIMEOUT    5
20
21
22 int run_test(int (test_function)(void), char *name)
23 {
24         bool terminated;
25         int rc, status;
26         pid_t pid;
27
28         /* Make sure output is flushed before forking */
29         fflush(stdout);
30
31         pid = fork();
32         if (pid == 0) {
33                 exit(test_function());
34         } else if (pid == -1) {
35                 perror("fork");
36                 return 1;
37         }
38
39         /* Wake us up in timeout seconds */
40         alarm(TIMEOUT);
41         terminated = false;
42
43 wait:
44         rc = waitpid(pid, &status, 0);
45         if (rc == -1) {
46                 if (errno != EINTR) {
47                         printf("unknown error from waitpid\n");
48                         return 1;
49                 }
50
51                 if (terminated) {
52                         printf("!! force killing %s\n", name);
53                         kill(pid, SIGKILL);
54                         return 1;
55                 } else {
56                         printf("!! killing %s\n", name);
57                         kill(pid, SIGTERM);
58                         terminated = true;
59                         alarm(KILL_TIMEOUT);
60                         goto wait;
61                 }
62         }
63
64         if (WIFEXITED(status))
65                 status = WEXITSTATUS(status);
66         else {
67                 if (WIFSIGNALED(status))
68                         printf("!! child died by signal %d\n", WTERMSIG(status));
69                 else
70                         printf("!! child died by unknown cause\n");
71
72                 status = 1; /* Signal or other */
73         }
74
75         return status;
76 }
77
78 static void alarm_handler(int signum)
79 {
80         /* Jut wake us up from waitpid */
81 }
82
83 static struct sigaction alarm_action = {
84         .sa_handler = alarm_handler,
85 };
86
87 int test_harness(int (test_function)(void), char *name)
88 {
89         int rc;
90
91         test_start(name);
92         test_set_git_version(GIT_VERSION);
93
94         if (sigaction(SIGALRM, &alarm_action, NULL)) {
95                 perror("sigaction");
96                 test_error(name);
97                 return 1;
98         }
99
100         rc = run_test(test_function, name);
101
102         test_finish(name, rc);
103
104         return rc;
105 }