From b13a0c69bb42b6b01c65bc17e71f8f1d46726cfa Mon Sep 17 00:00:00 2001 From: Davin McCall Date: Thu, 19 Nov 2015 11:02:18 +0000 Subject: [PATCH] Add the "termsignal" setting to process services. This allows an additional signal (alongside SIGTERM) to be sent to the process to terminate it. --- load_service.cc | 21 +++++++++++++++++++++ service.cc | 3 +++ service.h | 9 +++++++++ 3 files changed, 33 insertions(+) diff --git a/load_service.cc b/load_service.cc index fcfcab8..46887cd 100644 --- a/load_service.cc +++ b/load_service.cc @@ -161,6 +161,15 @@ static string read_setting_value(string_iterator & i, string_iterator end, return rval; } +static int signalNameToNumber(std::string &signame) +{ + if (signame == "HUP") return SIGHUP; + if (signame == "INT") return SIGINT; + if (signame == "QUIT") return SIGQUIT; + if (signame == "USR1") return SIGUSR1; + if (signame == "USR2") return SIGUSR2; + return -1; +} // Find a service record, or load it from file. If the service has // dependencies, load those also. @@ -201,6 +210,7 @@ ServiceRecord * ServiceSet::loadServiceRecord(const char * name) std::list depends_soft; string logfile; OnstartFlags onstart_flags; + int term_signal = -1; // additional termination signal string line; bool auto_restart = false; @@ -288,6 +298,16 @@ ServiceRecord * ServiceSet::loadServiceRecord(const char * name) } } } + else if (setting == "termsignal") { + string signame = read_setting_value(i, end, nullptr); + int signo = signalNameToNumber(signame); + if (signo == -1) { + throw new ServiceDescriptionExc(name, "Unknown/unsupported termination signal: " + signame); + } + else { + term_signal = signo; + } + } else { throw ServiceDescriptionExc(name, "Unknown setting: " + setting); } @@ -307,6 +327,7 @@ ServiceRecord * ServiceSet::loadServiceRecord(const char * name) rval->setLogfile(logfile); rval->setAutoRestart(auto_restart); rval->setOnstartFlags(onstart_flags); + rval->setExtraTerminationSignal(term_signal); *iter = rval; break; } diff --git a/service.cc b/service.cc index fa52aa7..bc98925 100644 --- a/service.cc +++ b/service.cc @@ -514,6 +514,9 @@ void ServiceRecord::allDepsStopped() if (pid != -1) { // The process is still kicking on - must actually kill it. kill(pid, SIGTERM); + if (term_signal != -1) { + kill(pid, term_signal); + } // Now we wait; the rest is done in process_child_callback } else { diff --git a/service.h b/service.h index 4eab4b1..b391cc8 100644 --- a/service.h +++ b/service.h @@ -1,6 +1,7 @@ #include #include #include +#include #include "ev.h" /* @@ -187,6 +188,8 @@ class ServiceRecord // case if for example the process dies; the service, // and all its dependencies, MUST be stopped. + int term_signal = -1; // signal to use for process termination + // Implementation details pid_t pid; /* PID of the process. If state is STARTING or STOPPING, @@ -294,6 +297,12 @@ class ServiceRecord { this->onstart_flags = flags; } + + // Set an additional signal (other than SIGTERM) to be used to terminate the process + void setExtraTerminationSignal(int signo) + { + this->term_signal = signo; + } const char *getServiceName() const { return service_name.c_str(); } ServiceState getState() const { return service_state; } -- 2.25.1