Fawkes API Fawkes Development Version
signal.cpp
1
2/***************************************************************************
3 * signal.cpp - This header defines a trule OOo signal handler
4 * based on
5 * Douglas C. Schmidt
6 * "Applying Design Patterns to Simplify Signal Handling"
7 * http://www.cs.wustl.edu/~schmidt/signal-patterns.html
8 *
9 * Generated: Thu Jan 12 22:55:34 2006
10 * Copyright 2005-2006 Tim Niemueller [www.niemueller.de]
11 *
12 ****************************************************************************/
13
14/* This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version. A runtime exception applies to
18 * this software (see LICENSE.GPL_WRE file mentioned below for details).
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU Library General Public License for more details.
24 *
25 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
26 */
27
28#include <utils/system/signal.h>
29
30#include <cstdlib>
31
32namespace fawkes {
33
34/** @class SignalHandler utils/system/signal.h
35 * Interface for signal handling.
36 * Derive this class and implement handle_signal() to handle signals.
37 * The handler must then be registered via SignalManager::register_handler().
38 * From then on handle_signal() is called if the desired signal has been received.
39 *
40 * @fn SignalHandler::~SignalHandler()
41 * Virtual destructor.
42 *
43 * @fn void SignalHandler::handle_signal(int signum)
44 * Signal hanlding method.
45 * Implement this method with the action you want to perform on the registered
46 * signals.
47 * @param signum signal number of triggered signal
48 *
49 * @author Tim Niemueller
50 */
51
52/** @class SignalManager utils/system/signal.h
53 * System signal manager.
54 * This class dispatches signals received from the system to the appropriate
55 * handlers or sets a signal to be ignored.
56 * This class is never instantiated but rather you just register a handler.
57 * After you are done with signal handling call finalize() to free the
58 * use resources and de-register all signal handlers at once.
59 *
60 * @author Tim Niemueller
61 */
62
63SignalManager *SignalManager::instance_ = NULL;
64SignalHandler *SignalManager::signal_handlers_[NSIG];
65
66/** Invalid constructor. */
67SignalManager::SignalManager()
68{
69}
70
71/** Invalid copy constructor. */
72SignalManager::SignalManager(const SignalManager &cc)
73{
74}
75
76/** Get the SignalManager instance
77 * @return SignalManager instance
78 */
79SignalManager *
81{
82 if (instance_ == NULL) {
83 instance_ = new SignalManager();
84 for (unsigned int i = 0; i < NSIG; ++i) {
85 signal_handlers_[i] = NULL;
86 }
87 }
88
89 return instance_;
90}
91
92/** Finalize (and free) the SignalManager instance, this does NOT
93 * implicitly delete the signal handlers, you have to do this by yourself
94 */
95void
97{
98 if (instance_ != NULL) {
99 for (unsigned int i = 0; i < NSIG; ++i) {
100 restore_default(i);
101 }
102 delete instance_;
103 instance_ = NULL;
104 }
105}
106
107/** Register a SignalHandler for a signal
108 * @param signum The signal number from <signal.h>
109 * @param handler The SignalHandler that should handle this event
110 * @return The SignalManager registered before, maybe NULL if there was none
111 */
114{
115 if (signum < NSIG) {
116 SignalHandler *old = signal_handlers_[signum];
117 signal_handlers_[signum] = handler;
118
119 // Register the <dispatcher> to handle this <signum>.
120 struct sigaction sa;
121 sa.sa_handler = SignalManager::dispatcher;
122 sigemptyset(&sa.sa_mask);
123 sa.sa_flags = 0;
124 sigaction(signum, &sa, 0);
125
126 return old;
127 } else {
128 return NULL;
129 }
130}
131
132/** Unregister a SignalHandler for a signal
133 * @param signum The signal number from <signal.h>
134 */
135void
137{
138 restore_default(signum);
139}
140
141/** Unregister a SignalHandler for a signal
142 * @param handler The SignalHandler you want to unregister, will unregister
143 * all signals this handler was registered for
144 */
145void
147{
148 for (unsigned int i = 0; i < NSIG; ++i) {
149 if (signal_handlers_[i] == handler) {
150 restore_default(i);
151 }
152 }
153}
154
155void
156SignalManager::restore_default(int signum)
157{
158 if (signum < NSIG) {
159 signal_handlers_[signum] = NULL;
160
161 // ignore this signal
162 struct sigaction sa;
163 sa.sa_handler = SIG_DFL;
164 sigemptyset(&sa.sa_mask);
165 sa.sa_flags = 0;
166 sigaction(signum, &sa, 0);
167 }
168}
169
170/** Ignore a signal
171 * @param signum The signal number from <signal.h>
172 */
173void
175{
176 if (signum < NSIG) {
177 signal_handlers_[signum] = NULL;
178
179 // ignore this signal
180 struct sigaction sa;
181 sa.sa_handler = SIG_IGN;
182 sigemptyset(&sa.sa_mask);
183 sa.sa_flags = 0;
184 sigaction(signum, &sa, 0);
185 }
186}
187
188/** Dispatch incoming signal to appropriate handler.
189 * @param signum signal received.
190 */
191void
192SignalManager::dispatcher(int signum)
193{
194 if (signal_handlers_[signum] != NULL) {
195 signal_handlers_[signum]->handle_signal(signum);
196 }
197}
198
199} // end namespace fawkes
Interface for signal handling.
Definition: signal.h:36
virtual void handle_signal(int signal)=0
Signal hanlding method.
System signal manager.
Definition: signal.h:45
static void finalize()
Finalize (and free) the SignalManager instance, this does NOT implicitly delete the signal handlers,...
Definition: signal.cpp:96
static void ignore(int signum)
Ignore a signal.
Definition: signal.cpp:174
static SignalManager * instance()
Get the SignalManager instance.
Definition: signal.cpp:80
static void unregister_handler(int signum)
Unregister a SignalHandler for a signal.
Definition: signal.cpp:136
static SignalHandler * register_handler(int signum, SignalHandler *handler)
Register a SignalHandler for a signal.
Definition: signal.cpp:113
Fawkes library namespace.