* setup now deletes old inittab entries if they were present
[citadel.git] / webcit / ctdlsvc.c
1 /*
2  * $Id: $
3  *
4  * This is just a quick little hack to start a program in the background,
5  * and automatically restart it if it exits with a nonzero exit status.
6  *
7  */
8
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <stdio.h>
12 #include <sys/types.h>
13 #include <sys/wait.h>
14 #include <errno.h>
15 #include <signal.h>
16
17 char *pidfilename = NULL;
18 pid_t current_child = 0;
19
20 RETSIGTYPE graceful_shutdown(int signum) {
21         kill(current_child, signum);
22         if (pidfilename != NULL) {
23                 unlink(pidfilename);
24         }
25         exit(0);
26 }
27         
28
29 int main(int argc, char **argv)
30 {
31         pid_t child = 0;
32         int status = 0;
33         FILE *fp;
34
35         --argc;
36         ++argv;
37
38         pidfilename = argv[0];
39         --argc;
40         ++argv;
41
42         if (access(argv[0], X_OK)) {
43                 fprintf(stderr, "%s: cannot execute\n", argv[0]);
44                 exit(1);
45         }
46
47         close(1);
48         close(2);
49         signal(SIGHUP, SIG_IGN);
50         signal(SIGINT, SIG_IGN);
51         signal(SIGQUIT, SIG_IGN);
52
53         child = fork();
54         if (child != 0) {
55                 fp = fopen(pidfilename, "w");
56                 if (fp != NULL) {
57                         fprintf(fp, "%d\n", child);
58                         fclose(fp);
59                 }
60                 exit(0);
61         }
62
63         do {
64                 current_child = fork();
65
66                 signal(SIGTERM, graceful_shutdown);
67         
68                 if (current_child < 0) {
69                         perror("fork");
70                         exit(errno);
71                 }
72         
73                 else if (current_child == 0) {
74                         exit(execvp(argv[0], &argv[0]));
75                 }
76         
77                 else {
78                         waitpid(current_child, &status, 0);
79                 }
80
81         } while (status != 0);
82
83         unlink(pidfilename);
84         exit(0);
85 }
86