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 
32 namespace 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 
63 SignalManager *SignalManager::instance_ = NULL;
64 SignalHandler *SignalManager::signal_handlers_[NSIG];
65 
66 /** Invalid constructor. */
67 SignalManager::SignalManager()
68 {
69 }
70 
71 /** Invalid copy constructor. */
72 SignalManager::SignalManager(const SignalManager &cc)
73 {
74 }
75 
76 /** Get the SignalManager instance
77  * @return SignalManager instance
78  */
79 SignalManager *
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  */
95 void
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  */
135 void
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  */
145 void
147 {
148  for (unsigned int i = 0; i < NSIG; ++i) {
149  if (signal_handlers_[i] == handler) {
150  restore_default(i);
151  }
152  }
153 }
154 
155 void
156 SignalManager::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  */
173 void
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  */
191 void
192 SignalManager::dispatcher(int signum)
193 {
194  if (signal_handlers_[signum] != NULL) {
195  signal_handlers_[signum]->handle_signal(signum);
196  }
197 }
198 
199 } // end namespace fawkes
fawkes::SignalHandler
Interface for signal handling.
Definition: signal.h:36
fawkes::SignalManager::finalize
static void finalize()
Finalize (and free) the SignalManager instance, this does NOT implicitly delete the signal handlers,...
Definition: signal.cpp:96
fawkes::SignalManager::ignore
static void ignore(int signum)
Ignore a signal.
Definition: signal.cpp:174
fawkes::SignalManager::instance
static SignalManager * instance()
Get the SignalManager instance.
Definition: signal.cpp:80
fawkes::SignalManager
System signal manager.
Definition: signal.h:45
fawkes::SignalManager::register_handler
static SignalHandler * register_handler(int signum, SignalHandler *handler)
Register a SignalHandler for a signal.
Definition: signal.cpp:113
fawkes::SignalManager::unregister_handler
static void unregister_handler(int signum)
Unregister a SignalHandler for a signal.
Definition: signal.cpp:136
fawkes
Fawkes library namespace.
fawkes::SignalHandler::handle_signal
virtual void handle_signal(int signal)=0
Signal hanlding method.