#include #include #include #include #include #include #include #include #include #include #include "utils.h" #include "log.h" #define _POSIX_PATH_MAX 256 char *arg0 = NULL; static void sighandler_child(int signo) { switch (signo) { case SIGHUP: if (getppid() == 1) { N("Master process %d died, exiting", getpgrp()); exit(EXIT_SUCCESS); } break; } } int set_child_sighandler(void) { /* not portable */ if (prctl(PR_SET_PDEATHSIG, SIGHUP) != 0) return 1; return signal(SIGHUP, sighandler_child) == SIG_ERR; } void set_procname(const char *new_arg0) { assert(arg0); memset(arg0, 0, _POSIX_PATH_MAX); strncpy(arg0, new_arg0, _POSIX_PATH_MAX); } pid_t daemonize(int stay_foreground) { int status = -1; pid_t pid; /* Fork off the parent process */ pid = fork(); /* An error occurred */ if (pid < 0) return pid; /* Success: Let the parent terminate */ if (pid > 0) { if (!stay_foreground) exit(EXIT_SUCCESS); waitpid(-1, &status, 0); exit(EXIT_SUCCESS); } /* On success: The child process becomes session leader */ if (!stay_foreground && setsid() < 0) { E_STRERR("setsid"); exit(EXIT_FAILURE); } /* Catch, ignore and handle signals */ //TODO: Implement a working signal handler */ //signal(SIGCHLD, SIG_IGN); //signal(SIGHUP, SIG_IGN); /* Fork off for the second time*/ if (!stay_foreground) { pid = fork(); /* An error occurred */ if (pid < 0) exit(EXIT_FAILURE); /* Success: Let the parent terminate */ if (pid > 0) exit(EXIT_SUCCESS); } if (!stay_foreground && setpgrp()) { E_STRERR("setpgrp"); exit(EXIT_FAILURE); } /* Set new file permissions */ umask(0); if (stay_foreground) return pid; /* Change the working directory to the root directory */ /* or another appropriated directory */ // chdir("/"); /* Close all open file descriptors */ int x; for (x = sysconf(_SC_OPEN_MAX); x>=0; x--) { // close (x); } return pid; }