/** * @file main/GUI/exithandler.cpp * @brief Exit handlers for the eVaf main executable * @author Enar Vaikene * * Copyright (c) 2011 Enar Vaikene * * This file is part of the eVaf C++ cross-platform application development framework. * * This file can be used under the terms of the GNU General Public License * version 3.0 as published by the Free Software Foundation and appearing in * the file LICENSE included in the packaging of this file. Please review the * the following information to ensure the GNU General Public License version * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. * * Alternatively, this file may be used in accordance with the Commercial License * Agreement provided with the Software. */ #include "exithandler.h" #include #include #include #ifdef Q_OS_LINUX # include #endif #ifdef Q_OS_WIN32 # include #endif namespace eVaf { namespace GUI { namespace Internal { #ifdef Q_OS_LINUX /** * Signal handler on Linux * * Handles TERM and HUP signals and either quits or restarts the application. * * @TODO According to the signal(7) documentation, only "safe" functions can be called from the * signal handler. We don't know how safe it is to call iApp::quit() and iApp::restart() and * probably have to implement "safe" versions of these functions. */ static void signalHandler(int sig) { eVaf::Common::iApp * app = eVaf::Common::iApp::instance(); switch (sig) { case SIGTERM: if (app) app->quit(); else exit(0); break; case SIGHUP: if (app) app->restart(); break; } } #endif #ifdef Q_OS_WIN32 /** * Signal handler on Windows * * Either quits or restarts the application. * * @TODO Is there a similar concept of "safe" functions for Windows signal handlers? */ static BOOL WINAPI signalHandler(DWORD sig) { eVaf::Common::iApp * app = eVaf::Common::iApp::instance(); switch (sig) { case CTRL_C_EVENT: case CTRL_CLOSE_EVENT: case CTRL_LOGOFF_EVENT: case CTRL_SHUTDOWN_EVENT: if (app) app->quit(); else exit(0); return true; break; case CTRL_BREAK_EVENT: if (app) app->restart(); return true; break; } return false; } #endif } // namespace eVaf::GUI::Internal } // namespace eVaf::GUI } // namespace eVaf using namespace eVaf::GUI::Internal; bool installExitHandler() { #ifdef Q_OS_LINUX struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = signalHandler; if (sigaction(SIGTERM, &sa, NULL) != 0) { EVAF_FATAL_ERROR("sigaction() failed: %m"); return false; } if (sigaction(SIGHUP, &sa, NULL) != 0) { EVAF_FATAL_ERROR("sigaction() failed: %m"); return false; } #endif #ifdef Q_OS_WIN32 if (SetConsoleCtrlHandler(signalHandler, true) == 0) { EVAF_FATAL_ERROR("SetConsoleCtrlHandler() failed"); return false; } #endif return true; }