Add "signal-process-only" option to avoid signalling process group.
authorDavin McCall <davmac@davmac.org>
Fri, 22 Jun 2018 17:45:49 +0000 (18:45 +0100)
committerDavin McCall <davmac@davmac.org>
Fri, 22 Jun 2018 17:45:49 +0000 (18:45 +0100)
doc/manpages/dinit-service.5
src/baseproc-service.cc
src/includes/service.h
src/load-service.cc

index 4c735b8508bcbf997122e1305e5d3930f205c25d..f1be58dece62eb5cd578de38332a27f0d752dc70 100644 (file)
@@ -272,6 +272,10 @@ For scripted services, indicates that if the service startup process terminates
 via an interrupt signal (SIGINT), then the service should be considered started.
 Note that if the interrupt was issued by Dinit to cancel startup, the service
 will instead be considered stopped.
+.TP
+\fBsignal-process-only\fR
+Signal the service process only, rather than its entire process group, whenever
+sending it a signal for any reason.
 .RE
 .LP
 The next section contains example service descriptions including some of the
index 14d9f2a1bb58eb1cbd25fedc2c1e499e3ea652b4..42f603ddef70b548128e5a9ead96fd627df2feb2 100644 (file)
@@ -287,13 +287,18 @@ void base_process_service::kill_with_fire() noexcept
 
 void base_process_service::kill_pg(int signo) noexcept
 {
-    pid_t pgid = bp_sys::getpgid(pid);
-    if (pgid == -1) {
-        // only should happen if pid is invalid, which should never happen...
-        log(loglevel_t::ERROR, get_name(), ": can't signal process: ", strerror(errno));
-        return;
+    if (onstart_flags.signal_process_only) {
+        bp_sys::kill(pid, signo);
+    }
+    else {
+        pid_t pgid = bp_sys::getpgid(pid);
+        if (pgid == -1) {
+            // only should happen if pid is invalid, which should never happen...
+            log(loglevel_t::ERROR, get_name(), ": can't signal process: ", strerror(errno));
+            return;
+        }
+        bp_sys::kill(-pgid, signo);
     }
-    bp_sys::kill(-pgid, signo);
 }
 
 void base_process_service::timer_expired() noexcept
index 6585028da82db3a24519412d1fe8030634e18aec..bc3beccfaaa1a162a5da15424945bb9f0d8c7635 100644 (file)
@@ -122,10 +122,11 @@ struct service_flags_t {
     bool pass_cs_fd : 1;  // pass this service a control socket connection via fd
     bool start_interruptible : 1; // the startup of this service process is ok to interrupt with SIGINT
     bool skippable : 1;   // if interrupted the service is skipped (scripted services)
+    bool signal_process_only : 1;  // signal the session process, not the whole group
     
-    service_flags_t() noexcept : rw_ready(false), log_ready(false),
-            no_sigterm(false), runs_on_console(false), starts_on_console(false),
-            pass_cs_fd(false), start_interruptible(false), skippable(false)
+    service_flags_t() noexcept : rw_ready(false), log_ready(false), no_sigterm(false),
+            runs_on_console(false), starts_on_console(false), pass_cs_fd(false),
+            start_interruptible(false), skippable(false), signal_process_only(false)
     {
     }
 };
index b26d318bc8d523f81ea82a97ee80972fd53bbdf1..30ce03abf24eb4f1e228d8638696b3b0215ace85 100644 (file)
@@ -607,6 +607,9 @@ service_record * dirload_service_set::load_service(const char * name)
                         else if (option_txt == "skippable") {
                             onstart_flags.skippable = true;
                         }
+                        else if (option_txt == "signal-process-only") {
+                            onstart_flags.signal_process_only = true;
+                        }
                         else {
                             throw service_description_exc(name, "Unknown option: " + option_txt);
                         }