r14628: sync timelimit.c with the version from the build-farm repository
[kai/samba-autobuild/.git] / source3 / script / tests / timelimit.c
1 /* run a command with a limited timeout
2    tridge@samba.org, June 2005
3
4    attempt to be as portable as possible (fighting posix all the way)
5 */
6 #include <stdio.h>
7 #include <string.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <signal.h>
11 #include <errno.h>
12 #include <sys/types.h>
13 #include <sys/wait.h>
14
15 static pid_t child_pid;
16
17 static void usage(void)
18 {
19         printf("usage: timelimit <time> <command>\n");
20         printf("   SIGALRM - passes SIGKILL to command's process group and exit(1)\n");
21         printf("   SIGUSR1 - passes SIGTERM to command's process group\n");
22         printf("   SIGTERM - passes SIGTERM to command's process group and exit(0)\n");
23 }
24
25 static void sig_alrm(int sig)
26 {
27         fprintf(stderr, "\nMaximum time expired in timelimit - killing\n");
28         kill(-child_pid, SIGKILL);
29         exit(1);
30 }
31
32 static void sig_term(int sig)
33 {
34         kill(-child_pid, SIGTERM);
35         exit(0);
36 }
37
38 static void sig_usr1(int sig)
39 {
40         kill(-child_pid, SIGTERM);
41 }
42
43 static void new_process_group(void)
44 {
45 #ifdef BSD_SETPGRP
46         if (setpgrp(0,0) == -1) {
47                 perror("setpgrp");
48                 exit(1);
49         }
50 #else
51         if (setpgrp() == -1) {
52                 perror("setpgrp");
53                 exit(1);
54         }
55 #endif
56 }
57
58
59 int main(int argc, char *argv[])
60 {
61         int maxtime, ret=1;
62         pid_t pgid;
63
64         if (argc < 3) {
65                 usage();
66                 exit(1);
67         }
68
69         maxtime = atoi(argv[1]);
70
71         child_pid = fork();
72         if (child_pid == 0) {
73                 new_process_group();
74                 execvp(argv[2], argv+2);
75                 perror(argv[2]);
76                 exit(1);
77         }
78
79         signal(SIGTERM, sig_term);
80         signal(SIGUSR1, sig_usr1);
81         signal(SIGALRM, sig_alrm);
82         alarm(maxtime);
83
84         do {
85                 int status;
86                 pid_t pid = wait(&status);
87                 if (pid != -1) {
88                         ret = WEXITSTATUS(status);
89                 } else if (errno == ECHILD) {
90                         break;
91                 }
92         } while (1);
93
94         kill(-child_pid, SIGKILL);
95
96         exit(ret);
97 }