diff --git a/src/launcher/booster.cpp b/src/launcher/booster.cpp index c2d73ad..5581e03 100644 --- a/src/launcher/booster.cpp +++ b/src/launcher/booster.cpp @@ -228,7 +228,7 @@ void Booster::renameProcess(int parentArgc, char** parentArgv) } } - // Set the process name using prctl, killall and top use it + // Set the process name using prctl, 'killall' and 'top' use it if ( prctl(PR_SET_NAME, basename(newProcessName)) == -1 ) Logger::logError("Booster: on set new process name: %s ", strerror(errno)); diff --git a/src/launcher/daemon.cpp b/src/launcher/daemon.cpp index dde4ae9..7443511 100644 --- a/src/launcher/daemon.cpp +++ b/src/launcher/daemon.cpp @@ -73,7 +73,7 @@ Daemon::Daemon(int & argc, char * argv[]) : if (pipe(m_pipefd) == -1) { - Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Creating a pipe failed!!!\n"); + Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Creating a pipe failed!\n"); } // Daemonize if desired diff --git a/src/launcher/mbooster.cpp b/src/launcher/mbooster.cpp index adb855b..dc1269c 100644 --- a/src/launcher/mbooster.cpp +++ b/src/launcher/mbooster.cpp @@ -23,6 +23,7 @@ #include #include +#include #ifdef HAVE_MCOMPONENTCACHE #include @@ -31,6 +32,69 @@ const string MBooster::m_socketId = "/tmp/boostm"; const string MBooster::m_temporaryProcessName = "booster-m"; int MBooster::m_ProcessID = 0; +int MBooster::m_sighupFd[2]; +struct sigaction MBooster::m_oldSigAction; + +MBooster::MBooster() +{ + // Install signals handler e.g. to exit cleanly if launcher dies. + // This is a problem because MBooster runs a Qt event loop. + setupUnixSignalHandlers(); + + // Create socket pair for SIGTERM + if (::socketpair(AF_UNIX, SOCK_STREAM, 0, m_sighupFd)) + { + Logger::logError("Couldn't create HUP socketpair"); + } + else + { + // Install a socket notifier on the socket + m_snHup.reset(new QSocketNotifier(m_sighupFd[1], QSocketNotifier::Read, this)); + connect(m_snHup.get(), SIGNAL(activated(int)), this, SLOT(handleSigHup())); + } +} + +// +// All this signal handling code is taken from Qt's Best Practices: +// http://doc.qt.nokia.com/latest/unix-signals.html +// + +void MBooster::hupSignalHandler(int) +{ + char a = 1; + ::write(m_sighupFd[0], &a, sizeof(a)); +} + +void MBooster::handleSigHup() +{ + ::exit(EXIT_SUCCESS); +} + +bool MBooster::setupUnixSignalHandlers() +{ + struct sigaction hup; + + hup.sa_handler = MBooster::hupSignalHandler; + sigemptyset(&hup.sa_mask); + hup.sa_flags |= SA_RESTART; + + if (sigaction(SIGHUP, &hup, &m_oldSigAction) > 0) + { + return false; + } + + return true; +} + +bool MBooster::restoreUnixSignalHandlers() +{ + if (sigaction(SIGHUP, &m_oldSigAction, 0) > 0) + { + return false; + } + + return true; +} const string & MBooster::socketId() const { @@ -88,9 +152,12 @@ bool MBooster::readCommand() // start another thread to listen connection from invoker QtConcurrent::run(this, &MBooster::accept); - // run event loop so MApplication and MApplicationWindow objects can receive notifications + // Run event loop so MApplication and MApplicationWindow objects can receive notifications MApplication::exec(); + // Restore signal handlers to previous values + restoreUnixSignalHandlers(); + // Receive application data from the invoker if(!m_conn->receiveApplicationData(m_app)) { diff --git a/src/launcher/mbooster.h b/src/launcher/mbooster.h index 98f14e1..5a5605b 100644 --- a/src/launcher/mbooster.h +++ b/src/launcher/mbooster.h @@ -22,7 +22,12 @@ #include "booster.h" #include +#include +#include +using std::tr1::shared_ptr; + +#include /*! \class MBooster @@ -40,7 +45,7 @@ class MBooster : public QObject, public Booster public: //! \brief Constructor - MBooster() {}; + MBooster(); //! \brief Destructor virtual ~MBooster() {}; @@ -80,6 +85,15 @@ public: */ static int processId(); + //! UNIX signal handler for SIGHUP + static void hupSignalHandler(int unused); + + //! Setup UNIX signal handlers + static bool setupUnixSignalHandlers(); + + //! Restore UNIX signal handlers to previous values + static bool restoreUnixSignalHandlers(); + protected: //! \reimp @@ -106,12 +120,27 @@ private: void accept(); -#ifdef UNIT_TEST - friend class Ut_MBooster; -#endif + //! Socket pair used to get SIGHUP + static int m_sighupFd[2]; + + //! Socket notifier used for m_sighupFd + shared_ptr m_snHup; + + //! Old sigaction struct + static struct sigaction m_oldSigAction; + +private slots: + + //! Qt signal handler for SIGHUP. + void handleSigHup(); signals: + void connectionAccepted(); + +#ifdef UNIT_TEST + friend class Ut_MBooster; +#endif }; #endif // MBOOSTER_H