aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rc/supervise-daemon.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/src/rc/supervise-daemon.c b/src/rc/supervise-daemon.c
index 276ff2fb..8fd41006 100644
--- a/src/rc/supervise-daemon.c
+++ b/src/rc/supervise-daemon.c
@@ -267,6 +267,56 @@ static char *make_cmdline(char **argv)
return cmdline;
}
+static pid_t exec_command(char *cmd)
+{
+ char *file;
+ pid_t pid = -1;
+ sigset_t full;
+ sigset_t old;
+ struct sigaction sa;
+
+ file = rc_service_resolve(svcname);
+ if (!exists(file)) {
+ free(file);
+ return 0;
+ }
+
+ /* We need to block signals until we have forked */
+ memset(&sa, 0, sizeof (sa));
+ sa.sa_handler = SIG_DFL;
+ sigemptyset(&sa.sa_mask);
+ sigfillset(&full);
+ sigprocmask(SIG_SETMASK, &full, &old);
+
+ pid = fork();
+ if (pid == 0) {
+ /* Restore default handlers */
+ sigaction(SIGCHLD, &sa, NULL);
+ sigaction(SIGHUP, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGQUIT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGUSR1, &sa, NULL);
+ sigaction(SIGWINCH, &sa, NULL);
+
+ /* Unmask signals */
+ sigprocmask(SIG_SETMASK, &old, NULL);
+
+ /* Safe to run now */
+ execl(file, file, cmd, (char *) NULL);
+ syslog(LOG_ERR, "unable to exec `%s': %s\n",
+ file, strerror(errno));
+ _exit(EXIT_FAILURE);
+ }
+
+ if (pid == -1)
+ syslog(LOG_ERR, "fork: %s\n",strerror (errno));
+
+ sigprocmask(SIG_SETMASK, &old, NULL);
+ free(file);
+ return pid;
+}
+
static void child_process(char *exec, char **argv)
{
RC_STRINGLIST *env_list;
@@ -537,13 +587,13 @@ static void supervisor(char *exec, char **argv)
do_healthcheck = 0;
alarm(0);
syslog(LOG_DEBUG, "running health check for %s", svcname);
- health_pid = exec_service(svcname, "healthcheck");
+ health_pid = exec_command("healthcheck");
health_status = rc_waitpid(health_pid);
if (WIFEXITED(health_status) && WEXITSTATUS(health_status) == 0)
alarm(healthchecktimer);
else {
syslog(LOG_WARNING, "health check for %s failed", svcname);
- health_pid = exec_service(svcname, "unhealthy");
+ health_pid = exec_command("unhealthy");
rc_waitpid(health_pid);
syslog(LOG_INFO, "stopping %s, pid %d", exec, child_pid);
nkilled = run_stop_schedule(applet, NULL, NULL, child_pid, 0,