]> code.citadel.org Git - citadel.git/blob - webcit/ctdlsvc.c
ctdlsvc now closes fd 0 in addition to fd 1 and 2
[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 void 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(0);
48         close(1);
49         close(2);
50         signal(SIGHUP, SIG_IGN);
51         signal(SIGINT, SIG_IGN);
52         signal(SIGQUIT, SIG_IGN);
53
54         child = fork();
55         if (child != 0) {
56                 fp = fopen(pidfilename, "w");
57                 if (fp != NULL) {
58                         fprintf(fp, "%d\n", child);
59                         fclose(fp);
60                 }
61                 exit(0);
62         }
63
64         do {
65                 current_child = fork();
66
67                 signal(SIGTERM, graceful_shutdown);
68         
69                 if (current_child < 0) {
70                         perror("fork");
71                         exit(errno);
72                 }
73         
74                 else if (current_child == 0) {
75                         exit(execvp(argv[0], &argv[0]));
76                 }
77         
78                 else {
79                         waitpid(current_child, &status, 0);
80                 }
81
82         } while (status != 0);
83
84         unlink(pidfilename);
85         exit(0);
86 }
87