int main (int argc, char **argv) { int collectd_argc = 0; char *collectd = NULL; char **collectd_argv = NULL; struct sigaction sa; int i = 0; /* parse command line options */ while (42) { int c = getopt (argc, argv, "hc:P:"); if (-1 == c) break; switch (c) { case 'c': collectd = optarg; break; case 'P': pidfile = optarg; break; case 'h': default: exit_usage (argv[0]); } } for (i = optind; i < argc; ++i) if (0 == strcmp (argv[i], "-f")) break; /* i < argc => -f already present */ collectd_argc = 1 + argc - optind + ((i < argc) ? 0 : 1); collectd_argv = (char **)calloc (collectd_argc + 1, sizeof (char *)); if (NULL == collectd_argv) { fprintf (stderr, "Out of memory."); return 3; } collectd_argv[0] = (NULL == collectd) ? "collectd" : collectd; if (i == argc) collectd_argv[collectd_argc - 1] = "-f"; for (i = optind; i < argc; ++i) collectd_argv[i - optind + 1] = argv[i]; collectd_argv[collectd_argc] = NULL; openlog ("collectdmon", LOG_CONS | LOG_PID, LOG_DAEMON); if (-1 == daemonize ()) return 1; sa.sa_handler = sig_int_term_handler; sa.sa_flags = 0; sigemptyset (&sa.sa_mask); if (0 != sigaction (SIGINT, &sa, NULL)) { syslog (LOG_ERR, "Error: sigaction() failed: %s", strerror (errno)); return 1; } if (0 != sigaction (SIGTERM, &sa, NULL)) { syslog (LOG_ERR, "Error: sigaction() failed: %s", strerror (errno)); return 1; } sa.sa_handler = sig_hup_handler; if (0 != sigaction (SIGHUP, &sa, NULL)) { syslog (LOG_ERR, "Error: sigaction() failed: %s", strerror (errno)); return 1; } while (0 == loop) { int status = 0; if (0 != collectd_start (collectd_argv)) { syslog (LOG_ERR, "Error: failed to start collectd."); break; } assert (0 < collectd_pid); while ((collectd_pid != waitpid (collectd_pid, &status, 0)) && (EINTR == errno)) if ((0 != loop) || (0 != restart)) collectd_stop (); collectd_pid = 0; log_status (status); check_respawn (); if (0 != restart) { syslog (LOG_INFO, "Info: restarting collectd"); restart = 0; } else if (0 == loop) syslog (LOG_WARNING, "Warning: restarting collectd"); } syslog (LOG_INFO, "Info: shutting down collectdmon"); pidfile_delete (); closelog (); free (collectd_argv); return 0; } /* main */
static void handle_killed_daemon(active_db_h * daemon, process_h * process) { assert(daemon); assert(daemon->name); assert(daemon->current_state); assert(daemon->current_state->name); assert(process); int rcode; D_("handle_killed_start(%s): initial status: \"%s\".\n", daemon->name, daemon->current_state->name); /* * Youst run if we checks for PID FILE */ if (daemon->current_state == &DAEMON_WAIT_FOR_PID_FILE && is(&FORKS, daemon)) { try_get_pid(daemon); return; } /* This service are gonna respawn, no need to set it stopped */ if (check_respawn(daemon)) { /* It is gonna respawn, free this process and forget */ initng_process_db_free(process); return; } /* Set local rcode, and free process */ rcode = process->r_code; initng_process_db_free(process); /* * Make sure r_code don't signal error (can be override by UP_ON_FAILURE. */ /* If daemon stoped by a SEGFAULT (SIGSEGV==11) this is always bad */ if (WTERMSIG(rcode) == 11) { initng_common_mark_service(daemon, &DAEMON_FAIL_START_SIGNAL); return; } /* if exit with sucess */ if (WEXITSTATUS(rcode) == 0) { /* OK! now daemon is STOPPED! */ initng_common_mark_service(daemon, &DAEMON_STOPPED); return; } /* else exitstatus is abouw 0 */ if (is(&DAEMON_FAIL_OK, daemon)) { /* It might be ok anyway */ initng_common_mark_service(daemon, &DAEMON_STOPPED); return; } /* This is also ok */ if (daemon->current_state->is == IS_STOPPING && is(&DAEMON_STOPS_BADLY, daemon)) { /* It might be ok anyway */ initng_common_mark_service(daemon, &DAEMON_STOPPED); return; } /* else fail by RCODE failure */ initng_common_mark_service(daemon, &DAEMON_FAIL_START_RCODE); }