]> code.citadel.org Git - citadel.git/blobdiff - citadel/sysdep.c
* purge ctdlsvc.c
[citadel.git] / citadel / sysdep.c
index c992adbe6f6b57a51a89c7cca953a09a807f05ce..df4f714f2e1fab35e8f442f2b20188e2585d7ae6 100644 (file)
@@ -750,34 +750,73 @@ void kill_session(int session_to_kill) {
        end_critical_section(S_SESSION_TABLE);
 }
 
-
+pid_t current_child;
+void graceful_shutdown(int signum) {
+       kill(current_child, signum);
+       unlink(file_pid_file);
+       exit(0);
+}
 
 
 /*
  * Start running as a daemon.
  */
 void start_daemon(int unused) {
-       int nullfd;
+       int status = 0;
+       pid_t child = 0;
+       FILE *fp;
+
+       current_child = 0;
 
        /* Close stdin/stdout/stderr and replace them with /dev/null.
         * We don't just call close() because we don't want these fd's
         * to be reused for other files.
         */
-       nullfd = open("/dev/null", O_RDWR);
-       if (nullfd < 0) {
-               fprintf(stderr, "/dev/null: %s\n", strerror(errno));
-               exit(2);
+       chdir(ctdl_run_dir);
+
+       child = fork();
+       if (child != 0) {
+               fp = fopen(file_pid_file, "w");
+               if (fp != NULL) {
+                       fprintf(fp, "%d\n", child);
+                       fclose(fp);
+               }
+               exit(0);
        }
-       dup2(nullfd, 0);
-       dup2(nullfd, 1);
-       dup2(nullfd, 2);
-       close(nullfd);
+       
+       signal(SIGHUP, SIG_IGN);
+       signal(SIGINT, SIG_IGN);
+       signal(SIGQUIT, SIG_IGN);
 
-       if (fork()) exit(0);
        setsid();
-       signal(SIGHUP,SIG_IGN);
-       signal(SIGINT,SIG_IGN);
-       signal(SIGQUIT,SIG_IGN);
+//     umask(0);
+        freopen("/dev/null", "r", stdin);
+        freopen("/dev/null", "w", stdout);
+        freopen("/dev/null", "w", stderr);
+
+       do {
+               current_child = fork();
+
+               signal(SIGTERM, graceful_shutdown);
+       
+               if (current_child < 0) {
+                       perror("fork");
+                       exit(errno);
+               }
+       
+               else if (current_child == 0) {
+                       return; /* continue starting citadel. */
+               }
+       
+               else {
+                       waitpid(current_child, &status, 0);
+               }
+
+       } while (status != 0);
+
+       unlink(file_pid_file);
+       exit(0);
+
 }