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 #include <cstdlib>
30 
31 namespace fawkes {
32 
33 /** @class SignalHandler utils/system/signal.h
34  * Interface for signal handling.
35  * Derive this class and implement handle_signal() to handle signals.
36  * The handler must then be registered via SignalManager::register_handler().
37  * From then on handle_signal() is called if the desired signal has been received.
38  *
39  * @fn SignalHandler::~SignalHandler()
40  * Virtual destructor.
41  *
42  * @fn void SignalHandler::handle_signal(int signum)
43  * Signal hanlding method.
44  * Implement this method with the action you want to perform on the registered
45  * signals.
46  * @param signum signal number of triggered signal
47  *
48  * @author Tim Niemueller
49  */
50 
51 /** @class SignalManager utils/system/signal.h
52  * System signal manager.
53  * This class dispatches signals received from the system to the appropriate
54  * handlers or sets a signal to be ignored.
55  * This class is never instantiated but rather you just register a handler.
56  * After you are done with signal handling call finalize() to free the
57  * use resources and de-register all signal handlers at once.
58  *
59  * @author Tim Niemueller
60  */
61 
62 SignalManager * SignalManager::__instance = NULL;
63 SignalHandler * SignalManager::__signal_handlers[NSIG];
64 
65 /** Invalid constructor. */
66 SignalManager::SignalManager()
67 {
68 }
69 
70 
71 /** Invalid copy constructor. */
72 SignalManager::SignalManager(const SignalManager &cc)
73 {
74 }
75 
76 
77 /** Get the SignalManager instance
78  * @return SignalManager instance
79  */
80 SignalManager *
82 {
83  if ( __instance == NULL ) {
84  __instance = new SignalManager();
85  for (unsigned int i = 0; i < NSIG; ++i) {
86  __signal_handlers[i] = NULL;
87  }
88  }
89 
90  return __instance;
91 }
92 
93 
94 /** Finalize (and free) the SignalManager instance, this does NOT
95  * implicitly delete the signal handlers, you have to do this by yourself
96  */
97 void
99 {
100  if ( __instance != NULL ) {
101  for (unsigned int i = 0; i < NSIG; ++i) {
102  restore_default(i);
103  }
104  delete __instance;
105  __instance = NULL;
106  }
107 }
108 
109 
110 /** Register a SignalHandler for a signal
111  * @param signum The signal number from <signal.h>
112  * @param handler The SignalHandler that should handle this event
113  * @return The SignalManager registered before, maybe NULL if there was none
114  */
117 {
118  if (signum < NSIG) {
119  SignalHandler *old = __signal_handlers[signum];
120  __signal_handlers[signum] = handler;
121 
122  // Register the <dispatcher> to handle this <signum>.
123  struct sigaction sa;
124  sa.sa_handler = SignalManager::dispatcher;
125  sigemptyset (&sa.sa_mask);
126  sa.sa_flags = 0;
127  sigaction (signum, &sa, 0);
128 
129  return old;
130  } else {
131  return NULL;
132  }
133 }
134 
135 
136 /** Unregister a SignalHandler for a signal
137  * @param signum The signal number from <signal.h>
138  */
139 void
141 {
142  restore_default(signum);
143 }
144 
145 
146 /** Unregister a SignalHandler for a signal
147  * @param handler The SignalHandler you want to unregister, will unregister
148  * all signals this handler was registered for
149  */
150 void
152 {
153 
154  for (unsigned int i = 0; i < NSIG; ++i) {
155  if ( __signal_handlers[i] == handler ) {
156  restore_default(i);
157  }
158  }
159 }
160 
161 
162 void
163 SignalManager::restore_default(int signum)
164 {
165  if (signum < NSIG) {
166  __signal_handlers[signum] = NULL;
167 
168  // ignore this signal
169  struct sigaction sa;
170  sa.sa_handler = SIG_DFL;
171  sigemptyset (&sa.sa_mask);
172  sa.sa_flags = 0;
173  sigaction (signum, &sa, 0);
174  }
175 }
176 
177 
178 /** Ignore a signal
179  * @param signum The signal number from <signal.h>
180  */
181 void
183 {
184  if (signum < NSIG) {
185  __signal_handlers[signum] = NULL;
186 
187  // ignore this signal
188  struct sigaction sa;
189  sa.sa_handler = SIG_IGN;
190  sigemptyset (&sa.sa_mask);
191  sa.sa_flags = 0;
192  sigaction (signum, &sa, 0);
193  }
194 }
195 
196 
197 /** Dispatch incoming signal to appropriate handler.
198  * @param signum signal received.
199  */
200 void
201 SignalManager::dispatcher(int signum)
202 {
203  if (__signal_handlers[signum] != NULL) {
204  __signal_handlers[signum]->handle_signal(signum);
205  }
206 }
207 
208 } // end namespace fawkes
static void finalize()
Finalize (and free) the SignalManager instance, this does NOT implicitly delete the signal handlers...
Definition: signal.cpp:98
virtual void handle_signal(int signal)=0
Signal hanlding method.
Fawkes library namespace.
Interface for signal handling.
Definition: signal.h:35
System signal manager.
Definition: signal.h:42
static SignalManager * instance()
Get the SignalManager instance.
Definition: signal.cpp:81
static void ignore(int signum)
Ignore a signal.
Definition: signal.cpp:182
static SignalHandler * register_handler(int signum, SignalHandler *handler)
Register a SignalHandler for a signal.
Definition: signal.cpp:116
static void unregister_handler(int signum)
Unregister a SignalHandler for a signal.
Definition: signal.cpp:140