From 3768e06584204f265cc4f12369712954a01ea16b Mon Sep 17 00:00:00 2001 From: Davin McCall Date: Mon, 3 Jul 2017 01:10:28 +0100 Subject: [PATCH] Use getpgid to determine process group of service process. Using pid (i.e. 'kill(-pid, signo)') doesn't work if the process has double-forked but not set a new process group for the child, and anyway it's not clear if POSIX actually guarantees that process group IDs will match process IDs. --- src/service.cc | 19 +++++++++++++++---- src/service.h | 3 +++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/service.cc b/src/service.cc index 6c249df..8fa93ec 100644 --- a/src/service.cc +++ b/src/service.cc @@ -1222,6 +1222,17 @@ void service_record::all_deps_stopped() noexcept stopped(); } +void base_process_service::kill_pg(int signo) noexcept +{ + pid_t pgid = getpgid(pid); + if (pgid == -1) { + // only should happen if pid is invalid, which should never happen... + log(LogLevel::ERROR, service_name, ": can't signal process: ", strerror(errno)); + return; + } + kill(-pgid, signo); +} + void base_process_service::all_deps_stopped() noexcept { waiting_for_deps = false; @@ -1230,10 +1241,10 @@ void base_process_service::all_deps_stopped() noexcept // group (-pid) rather than just the process as there's less risk then of creating // an orphaned process group: if (! onstart_flags.no_sigterm) { - kill(-pid, SIGTERM); + kill_pg(SIGTERM); } if (term_signal != -1) { - kill(-pid, term_signal); + kill_pg(term_signal); } // In most cases, the rest is done in handle_exit_status. @@ -1419,8 +1430,8 @@ void base_process_service::interrupt_start() noexcept void base_process_service::kill_with_fire() noexcept { if (pid != -1) { - log(LogLevel::WARN, "Service ", service_name, " exceeded allowed stop time; killing."); - kill(-pid, SIGKILL); + log(LogLevel::WARN, "Service ", service_name, "with pid ", pid, " exceeded allowed stop time; killing."); + kill_pg(SIGKILL); } } diff --git a/src/service.h b/src/service.h index 2ecbf7f..8e23593 100644 --- a/src/service.h +++ b/src/service.h @@ -656,6 +656,9 @@ class base_process_service : public service_record // Kill with SIGKILL void kill_with_fire() noexcept; + // Signal the process group of the service process + void kill_pg(int signo) noexcept; + public: base_process_service(service_set *sset, string name, service_type record_type_p, string &&command, std::list> &command_offsets, -- 2.25.1