unix/SignalHandlers: shut down if parent process dies in --no-daemon mode

By default, if the parent of a process dies, the process gets SIGHUP
and is supposed to shut down.  This however doesn't work for MPD,
because MPD redefines SIGHUP with a different meaning (like most
daemons do).

To work around this, we configure the kernel to send SIGTERM instead
of SIGHUP.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1706
This commit is contained in:
Max Kellermann 2023-03-06 12:53:19 +01:00
parent 6e700dab69
commit a0f6932ebe
4 changed files with 22 additions and 5 deletions

2
NEWS
View File

@ -3,6 +3,8 @@ ver 0.23.13 (not yet released)
- curl: fix busy loop after connection failed - curl: fix busy loop after connection failed
* output * output
- pipewire: fix corruption bug due to missing lock - pipewire: fix corruption bug due to missing lock
* Linux
- shut down if parent process dies in --no-daemon mode
ver 0.23.12 (2023/01/17) ver 0.23.12 (2023/01/17)
* input * input

View File

@ -482,7 +482,10 @@ MainConfigured(const CommandLineOptions &options,
#ifndef ANDROID #ifndef ANDROID
setup_log_output(); setup_log_output();
const ScopeSignalHandlersInit signal_handlers_init(instance); const ScopeSignalHandlersInit signal_handlers_init{
instance,
options.daemon,
};
#endif #endif
instance.io_thread.Start(); instance.io_thread.Start();

View File

@ -30,6 +30,10 @@
#include <csignal> #include <csignal>
#ifdef __linux__
#include <sys/prctl.h>
#endif
static constexpr Domain signal_handlers_domain("signal_handlers"); static constexpr Domain signal_handlers_domain("signal_handlers");
static void static void
@ -60,7 +64,7 @@ handle_reload_event(void *ctx) noexcept
#endif #endif
void void
SignalHandlersInit(Instance &instance) SignalHandlersInit(Instance &instance, bool daemon)
{ {
auto &loop = instance.event_loop; auto &loop = instance.event_loop;
@ -79,6 +83,14 @@ SignalHandlersInit(Instance &instance)
SignalMonitorRegister(SIGHUP, {&instance, handle_reload_event}); SignalMonitorRegister(SIGHUP, {&instance, handle_reload_event});
#endif #endif
if (!daemon) {
#ifdef __linux__
/* if MPD was not daemonized, shut it down when the
parent process dies */
prctl(PR_SET_PDEATHSIG, SIGTERM);
#endif
}
} }
void void

View File

@ -23,15 +23,15 @@
struct Instance; struct Instance;
void void
SignalHandlersInit(Instance &instance); SignalHandlersInit(Instance &instance, bool daemon);
void void
SignalHandlersFinish() noexcept; SignalHandlersFinish() noexcept;
class ScopeSignalHandlersInit { class ScopeSignalHandlersInit {
public: public:
ScopeSignalHandlersInit(Instance &instance) { ScopeSignalHandlersInit(Instance &instance, bool daemon) {
SignalHandlersInit(instance); SignalHandlersInit(instance, daemon);
} }
~ScopeSignalHandlersInit() noexcept { ~ScopeSignalHandlersInit() noexcept {