From 4c8ecba8114975fb318d9d100a3339e282077ca6 Mon Sep 17 00:00:00 2001 From: Alexey Shilov Date: Thu, 21 Jul 2011 15:51:59 +0300 Subject: [PATCH] Fixes: NB#273378 - Boosters should restore original signal handlers modified by applauncherd RevBy: Dmitry Rozenshtein, Pertti Kellomaki --- debian/changelog | 1 + src/launcherlib/daemon.cpp | 35 +++++++++++++++++++++++++++++------ src/launcherlib/daemon.h | 14 ++++++++++++++ src/launcherlib/main.cpp | 13 +++++++------ 4 files changed, 51 insertions(+), 12 deletions(-) diff --git a/debian/changelog b/debian/changelog index 2d0715b..d5113a7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ applauncherd (1.1.0) unstable; urgency=low * Fixes: NB#262604 - applauncherd not buildable with eglibc 2.12 * Fixes: NB#248543 - [SSU]:Error seen at 'invoker: error: Can't send signal to application: No such process ' + * Fixes: NB#273378 - Boosters should restore original signal handlers modified by applauncherd -- Juha Lintula Tue, 14 Jun 2011 14:55:06 +0300 diff --git a/src/launcherlib/daemon.cpp b/src/launcherlib/daemon.cpp index 6bd6b71..104db14 100644 --- a/src/launcherlib/daemon.cpp +++ b/src/launcherlib/daemon.cpp @@ -405,12 +405,8 @@ void Daemon::forkBooster(char type, int sleepTime) if (newPid == 0) /* Child process */ { - // Reset used signal handlers - signal(SIGCHLD, SIG_DFL); - signal(SIGTERM, SIG_DFL); - signal(SIGUSR1, SIG_DFL); - signal(SIGUSR2, SIG_DFL); - signal(SIGPIPE, SIG_DFL); + // Restore used signal handlers + restoreUnixSignalHandlers(); // Will get this signal if applauncherd dies prctl(PR_SET_PDEATHSIG, SIGHUP); @@ -767,6 +763,33 @@ void Daemon::killBoosters() // in order to automatically start new boosters. } +void Daemon::setUnixSignalHandler(int signum, sighandler_t handler) +{ + struct sigaction *oldAct = new struct sigaction(); + struct sigaction newAct; + + newAct.sa_handler = handler; + sigemptyset(&newAct.sa_mask); + newAct.sa_flags |= SA_RESTART; + if (sigaction(signum, &newAct, oldAct) == 0) + { + m_originalSigHandlers[signum] = oldAct; + } else { + throw std::runtime_error("Daemon: Failed to set signal handler"); + } +} + +void Daemon::restoreUnixSignalHandlers() +{ + for (SigHandlerMap::iterator it = m_originalSigHandlers.begin(); it != m_originalSigHandlers.end(); it++ ) + { + sigaction(it->first, it->second, NULL); + } + + m_originalSigHandlers.clear(); +} + + Daemon::~Daemon() { delete m_socketManager; diff --git a/src/launcherlib/daemon.h b/src/launcherlib/daemon.h index 4cbd8c4..fd25365 100644 --- a/src/launcherlib/daemon.h +++ b/src/launcherlib/daemon.h @@ -97,6 +97,16 @@ public: */ int sigPipeFd() const; + /*! + * Set unix signal handler and save its original value. + */ + void setUnixSignalHandler(int signum, sighandler_t handler); + + /*! + * Restore unix signal handlers to their saved values. + */ + void restoreUnixSignalHandlers(); + private: //! Disable copy-constructor @@ -221,6 +231,10 @@ private: //! Single instance plugin handle SingleInstance * m_singleInstance; + //! Original unix signal handlers are saved here + typedef map SigHandlerMap; + SigHandlerMap m_originalSigHandlers; + #ifdef UNIT_TEST friend class Ut_Daemon; #endif diff --git a/src/launcherlib/main.cpp b/src/launcherlib/main.cpp index f40f36e..f43dc27 100644 --- a/src/launcherlib/main.cpp +++ b/src/launcherlib/main.cpp @@ -93,12 +93,13 @@ DECL_EXPORT int main(int argc, char * argv[]) // Get fd for signal pipe. g_sigPipeFd = myDaemon.sigPipeFd(); - // Install signal handlers - signal(SIGCHLD, sigChldHandler); // reap zombies - signal(SIGTERM, sigTermHandler); // exit launcher - signal(SIGUSR1, sigUsr1Handler); // enter normal mode from boot mode - signal(SIGUSR2, sigUsr2Handler); // enter boot mode (same as --boot-mode) - signal(SIGPIPE, sigPipeHandler); // broken invoker's pipe + // Install signal handlers. The original handlers are saved + // in the daemon instance so that they can be restored in boosters. + myDaemon.setUnixSignalHandler(SIGCHLD, sigChldHandler); // reap zombies + myDaemon.setUnixSignalHandler(SIGTERM, sigTermHandler); // exit launcher + myDaemon.setUnixSignalHandler(SIGUSR1, sigUsr1Handler); // enter normal mode from boot mode + myDaemon.setUnixSignalHandler(SIGUSR2, sigUsr2Handler); // enter boot mode (same as --boot-mode) + myDaemon.setUnixSignalHandler(SIGPIPE, sigPipeHandler); // broken invoker's pipe // Run the main loop myDaemon.run();