]> code.citadel.org Git - citadel.git/blob - citadel/ctdlsvc.c
* When enumerating rooms in the drop-down list
[citadel.git] / citadel / 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 <sys/stat.h>
15 #include <errno.h>
16 #include <signal.h>
17 #include <fcntl.h>
18 #include <string.h>
19
20 char *pidfilename = NULL;
21 pid_t current_child = 0;
22
23 void graceful_shutdown(int signum) {
24         kill(current_child, signum);
25         if (pidfilename != NULL) {
26                 unlink(pidfilename);
27         }
28         exit(0);
29 }
30         
31
32 int main(int argc, char **argv)
33 {
34         pid_t child = 0;
35         int status = 0;
36         FILE *fp;
37 //      int nullfd;
38
39         --argc;
40         ++argv;
41
42         pidfilename = argv[0];
43         --argc;
44         ++argv;
45
46         if (access(argv[0], X_OK)) {
47                 fprintf(stderr, "%s: cannot execute\n", argv[0]);
48                 exit(1);
49         }
50
51         /* Close stdin/stdout/stderr and replace them with /dev/null.
52          * We don't just call close() because we don't want these fd's
53          * to be reused for other files.
54          */
55 /*
56         nullfd = open("/dev/null", O_RDWR);
57         if (nullfd < 0) {
58                 fprintf(stderr, "/dev/null: %s\n", strerror(errno));
59                 exit(2);
60         }
61         dup2(nullfd, 0);
62         dup2(nullfd, 1);
63         dup2(nullfd, 2);
64         close(nullfd);
65 */
66         signal(SIGHUP, SIG_IGN);
67         signal(SIGINT, SIG_IGN);
68         signal(SIGQUIT, SIG_IGN);
69
70         child = fork();
71         if (child != 0) {
72                 fp = fopen(pidfilename, "w");
73                 if (fp != NULL) {
74                         fprintf(fp, "%d\n", child);
75                         fclose(fp);
76                 }
77                 exit(0);
78         }
79         
80         setsid();
81         chdir("/");
82         umask(0);
83         freopen("/dev/null", "r", stdin);
84         freopen("/dev/null", "w", stdout);
85         freopen("/dev/null", "w", stderr);
86
87         do {
88                 current_child = fork();
89
90                 signal(SIGTERM, graceful_shutdown);
91         
92                 if (current_child < 0) {
93                         perror("fork");
94                         exit(errno);
95                 }
96         
97                 else if (current_child == 0) {
98                         exit(execvp(argv[0], &argv[0]));
99                 }
100         
101                 else {
102                         waitpid(current_child, &status, 0);
103                 }
104
105         } while (status != 0);
106
107         unlink(pidfilename);
108         exit(0);
109 }
110