]> vaikene.ee Git - evaf/blob - src/main/CLI/exithandler.cpp
Warning fixes and copyright update.
[evaf] / src / main / CLI / exithandler.cpp
1 /**
2 * @file main/CLI/exithandler.cpp
3 * @brief Exit handlers for the eVaf main executable
4 * @author Enar Vaikene
5 *
6 * Copyright (c) 2011-2019 Enar Vaikene
7 *
8 * This file is part of the eVaf C++ cross-platform application development framework.
9 *
10 * This file can be used under the terms of the GNU General Public License
11 * version 3.0 as published by the Free Software Foundation and appearing in
12 * the file LICENSE included in the packaging of this file. Please review the
13 * the following information to ensure the GNU General Public License version
14 * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
15 *
16 * Alternatively, this file may be used in accordance with the Commercial License
17 * Agreement provided with the Software.
18 */
19
20 #include "exithandler.h"
21
22 #include <Common/iLogger>
23 #include <Common/iApp>
24
25 #include <QtCore>
26
27 #if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
28 # include <signal.h>
29 #endif
30
31 #ifdef Q_OS_WIN32
32 # include <windows.h>
33 #endif
34
35 namespace eVaf {
36 namespace CLI {
37 namespace Internal {
38
39 #if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
40
41 /**
42 * Signal handler on Linux
43 *
44 * Handles TERM and HUP signals and either quits or restarts the application.
45 *
46 * @TODO According to the signal(7) documentation, only "safe" functions can be called from the
47 * signal handler. We don't know how safe it is to call iApp::quit() and iApp::restart() and
48 * probably have to implement "safe" versions of these functions.
49 */
50 static void signalHandler(int sig)
51 {
52 eVaf::Common::iApp * app = eVaf::Common::iApp::instance();
53
54 switch (sig) {
55 case SIGTERM:
56 if (app)
57 app->quit();
58 else
59 exit(0);
60 break;
61 case SIGHUP:
62 if (app)
63 app->restart();
64 break;
65 }
66 }
67
68 #endif
69
70 #ifdef Q_OS_WIN32
71
72 /**
73 * Signal handler on Windows
74 *
75 * Either quits or restarts the application.
76 *
77 * @TODO Is there a similar concept of "safe" functions for Windows signal handlers?
78 */
79 static BOOL WINAPI signalHandler(DWORD sig)
80 {
81 eVaf::Common::iApp * app = eVaf::Common::iApp::instance();
82
83 switch (sig) {
84 case CTRL_C_EVENT:
85 case CTRL_CLOSE_EVENT:
86 case CTRL_LOGOFF_EVENT:
87 case CTRL_SHUTDOWN_EVENT:
88 if (app)
89 app->quit();
90 else
91 exit(0);
92 return true;
93 break;
94 case CTRL_BREAK_EVENT:
95 if (app)
96 app->restart();
97 return true;
98 break;
99 }
100
101 return false;
102 }
103
104 #endif
105
106 } // namespace eVaf::GUI::Internal
107 } // namespace eVaf::GUI
108 } // namespace eVaf
109
110
111 bool eVaf::CLI::Internal::installExitHandler()
112 {
113
114 #if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
115 struct sigaction sa;
116 memset(&sa, 0, sizeof(sa));
117 sa.sa_handler = signalHandler;
118 if (sigaction(SIGTERM, &sa, nullptr) != 0) {
119 EVAF_FATAL_ERROR("sigaction() failed: %m");
120 return false;
121 }
122 if (sigaction(SIGHUP, &sa, nullptr) != 0) {
123 EVAF_FATAL_ERROR("sigaction() failed: %m");
124 return false;
125 }
126 #endif
127
128 #ifdef Q_OS_WIN32
129 if (SetConsoleCtrlHandler(signalHandler, true) == 0) {
130 EVAF_FATAL_ERROR("SetConsoleCtrlHandler() failed");
131 return false;
132 }
133 #endif
134
135 return true;
136 }