Index: gearmand/gearmand/gearmand.cc =================================================================== --- gearmand.orig/gearmand/gearmand.cc 2011-05-26 10:26:21.665386640 -0400 +++ gearmand/gearmand/gearmand.cc 2011-05-26 10:36:31.519348192 -0400 @@ -204,7 +204,11 @@ if (opt_daemon) { - gearmand::daemonize(false, true); + // pid_t pid= getpid(); + // std::cerr << std::endl << pid << " about to spawn child" << std::endl; + gearmand::daemonize(true, true, true); + // pid= getpid(); + // std::cerr << pid << " returned from daemonize" << std::endl; } if ((fds > 0 && _set_fdlimit(fds)) @@ -214,8 +218,13 @@ return EXIT_FAILURE; } - if (opt_daemon) - gearmand::daemon_is_ready(verbose_count == 0); + if (opt_daemon) { + // pid_t pid= getpid(); + // std::cerr << std::endl << pid << " about to spawn grandchild" << std::endl; + gearmand::daemonize(true, false, true); + // pid= getpid(); + // std::cerr << pid << " returned from daemonize" << std::endl; + } gearmand_verbose_t verbose= verbose_count > static_cast(GEARMAND_VERBOSE_CRAZY) ? GEARMAND_VERBOSE_CRAZY : static_cast(verbose_count); @@ -271,6 +280,14 @@ return EXIT_FAILURE; } + if (opt_daemon) + { + // pid_t pid= getpid(); + // std::cerr << pid << " about to signal parent that I'm up and running" << std::endl; + gearmand::daemon_is_ready(); + // std::cerr << pid << " parent process should have exited (making its parent process exit, too)" << std::endl; + } + gearmand_error_t ret; ret= gearmand_run(_gearmand); Index: gearmand/util/daemon.cc =================================================================== --- gearmand.orig/util/daemon.cc 2011-05-26 10:26:21.653386442 -0400 +++ gearmand/util/daemon.cc 2011-05-26 10:35:44.950587857 -0400 @@ -49,6 +49,8 @@ #include +// #include + namespace gearmand { @@ -59,121 +61,100 @@ static void sigusr1_handler(int sig) { - if (sig == SIGUSR1) - { + if (sig == SIGUSR1) { + pid_t pid= getpid(); + // std::cerr << pid << " got USR1 signal" << std::endl; _exit(EXIT_SUCCESS); } } } -bool daemon_is_ready(bool close_io) +void daemon_is_ready() { kill(parent_pid, SIGUSR1); - - if (not close_io) - return true;; - - int fd; - if ((fd = open("/dev/null", O_RDWR, 0)) < 0) - { - perror("open"); - return false; - } - else - { - if(dup2(fd, STDIN_FILENO) < 0) - { - perror("dup2 stdin"); - return false; - } - - if(dup2(fd, STDOUT_FILENO) < 0) - { - perror("dup2 stdout"); - return false; - } - - if(dup2(fd, STDERR_FILENO) < 0) - { - perror("dup2 stderr"); - return false; - } - - if (fd > STDERR_FILENO) - { - if (close(fd) < 0) - { - perror("close"); - return false; - } - } - } - - return true; } -#pragma GCC diagnostic ignored "-Wold-style-cast" - -bool daemonize(bool is_chdir, bool wait_sigusr1) +bool daemonize(bool nochdir, bool noclose, bool wait_sigusr1) { - pid_t child= -1; - - parent_pid= getpid(); - signal(SIGUSR1, sigusr1_handler); + int fd; + pid_t child= -1; - child= fork(); - - switch (child) - { - case -1: - return false; + parent_pid= getpid(); + signal(SIGUSR1, sigusr1_handler); - case 0: - break; + child= fork(); - default: - if (wait_sigusr1) - { - /* parent */ - int exit_code= EXIT_FAILURE; - int status; - while (waitpid(child, &status, 0) != child) - { } - - if (WIFEXITED(status)) + switch (child) + { + case -1: + return true; + case 0: + break; + default: + // std::cerr << parent_pid << " has child " << child << std::endl; + if (wait_sigusr1) { - exit_code= WEXITSTATUS(status); + /* parent */ + int exit_code= -1; + int status; + // std::cerr << parent_pid << " is waiting on child " << child << std::endl; + while (waitpid(child, &status, 0) != child) + { } + + // std::cerr << parent_pid << " had child " << child << " exit with status " << status << std::endl; + + if (WIFEXITED(status)) + { + exit_code= WEXITSTATUS(status); + } + if (WIFSIGNALED(status)) + { + exit_code= -1; + } + + // std::cerr << parent_pid << " exiting with status " << exit_code << std::endl; + _exit(exit_code); } - if (WIFSIGNALED(status)) + else { - exit_code= EXIT_FAILURE; + _exit(EXIT_SUCCESS); } - _exit(exit_code); - } - else - { - _exit(EXIT_SUCCESS); } - } - - /* child */ - if (setsid() == -1) - { - perror("setsid"); - return false; - } - if (is_chdir) - { - if (chdir("/") < 0) - { - perror("chdir"); - return false; + /* child */ + if (setsid() == -1) + return true; + + if (nochdir == 0) { + if(chdir("/") != 0) { + perror("chdir"); + return true; + } + } + + if (noclose == 0 && (fd = open("/dev/null", O_RDWR, 0)) != -1) { + if(dup2(fd, STDIN_FILENO) < 0) { + perror("dup2 stdin"); + return true; + } + if(dup2(fd, STDOUT_FILENO) < 0) { + perror("dup2 stdout"); + return true; + } + if(dup2(fd, STDERR_FILENO) < 0) { + perror("dup2 stderr"); + return true; + } + + if (fd > STDERR_FILENO) { + if(close(fd) < 0) { + perror("close"); + return true; + } + } } - } - - return true; + return false; } -} /* namespace drizzled */ +} /* namespace gearmand */ Index: gearmand/util/daemon.h =================================================================== --- gearmand.orig/util/daemon.h 2011-05-26 10:26:21.661386574 -0400 +++ gearmand/util/daemon.h 2011-05-26 10:35:10.958032929 -0400 @@ -36,7 +36,8 @@ namespace gearmand { -bool daemon_is_ready(bool close_io); -bool daemonize(bool is_chdir= true, bool wait_sigusr1= true); +bool daemonize(bool nochdir= true, bool noclose= true, bool wait_sigusr1= true); +void daemon_is_ready(); } +