From 80bd541787902eac9d24e796c6d31e49b173e3ac Mon Sep 17 00:00:00 2001 From: Davin McCall Date: Tue, 24 Nov 2015 00:03:10 +0000 Subject: [PATCH] Add "nosigterm" service setting to inhibit sending SIGTERM to service process. (Unless an aleternative signal is specified using 'termsignal', no termination signal will be sent). --- README | 13 +++++++++++++ load_service.cc | 4 ++++ service.cc | 14 ++++++++------ service.h | 5 ++++- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/README b/README index cf1a03a..7f20163 100644 --- a/README +++ b/README @@ -85,6 +85,7 @@ logfile = ... onstart = ... depends-on = (service name) waits-for = (service name) +termsignal = HUP | INT | QUIT | USR1 | USR2 command = (external script or executable and arguments) For a 'process' service, this is the process to run. @@ -109,3 +110,15 @@ waits-for = (service name) starting (or to fail starting) before commencing the start procedure for this service. Starting this service will automatically start the named service. + +termsignal = (signal) + Specifies an additional signal to send to the process when requesting it + to terminate (applies to 'process' services only). SIGTERM is always + sent along with the specified signal, unless the 'nosigterm' setting is + set true. + +nosigterm = yes | true | no | false + If true, the TERM signal will not be sent to the process to kill it. (If + an alternate signal is specified using the "termsignal" setting, that + signal will be sent instead; otherwise, no signal will be sent, and the + process must be killed by external means). diff --git a/load_service.cc b/load_service.cc index 87116ec..49bd28f 100644 --- a/load_service.cc +++ b/load_service.cc @@ -310,6 +310,10 @@ ServiceRecord * ServiceSet::loadServiceRecord(const char * name) term_signal = signo; } } + else if (setting == "nosigterm") { + string sigtermsetting = read_setting_value(i, end); + onstart_flags.no_sigterm = (sigtermsetting == "yes" || sigtermsetting == "true"); + } else { throw ServiceDescriptionExc(name, "Unknown setting: " + setting); } diff --git a/service.cc b/service.cc index 71ec4fc..291ae22 100644 --- a/service.cc +++ b/service.cc @@ -512,12 +512,14 @@ void ServiceRecord::allDepsStopped() { if (service_type == ServiceType::PROCESS) { 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 + // The process is still kicking on - must actually kill it. + if (! onstart_flags.no_sigterm) { + kill(pid, SIGTERM); + } + if (term_signal != -1) { + kill(pid, term_signal); + } + // Now we wait; the rest is done in process_child_callback } else { // The process is already dead. diff --git a/service.h b/service.h index 7f4ae22..2ad60ba 100644 --- a/service.h +++ b/service.h @@ -50,7 +50,10 @@ struct OnstartFlags { bool release_console : 1; bool rw_ready : 1; - OnstartFlags() noexcept : release_console(false), rw_ready(false) + // Not actually "onstart" commands: + bool no_sigterm : 1; // do not send SIGTERM + + OnstartFlags() noexcept : release_console(false), rw_ready(false), no_sigterm(false) { } }; -- 2.25.1