00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "config.h"
00033
00034 static char rcsid[] not_used =
00035 { "$Id: SignalHandler.cc 18500 2008-03-19 19:39:45Z jimg $"
00036 };
00037
00038 #include <signal.h>
00039 #include <pthread.h>
00040
00041 #ifdef HAVE_UNISTD_H
00042 #include <unistd.h>
00043 #endif
00044
00045 #include "SignalHandler.h"
00046 #include "util.h"
00047
00048 namespace libdap {
00049
00050 EventHandler *SignalHandler::d_signal_handlers[NSIG];
00051 Sigfunc *SignalHandler::d_old_handlers[NSIG];
00052 SignalHandler *SignalHandler::d_instance = 0;
00053
00054
00055
00056 static pthread_once_t instance_control = PTHREAD_ONCE_INIT;
00057
00059 void
00060 SignalHandler::initialize_instance()
00061 {
00062
00063 SignalHandler::d_instance = new SignalHandler;
00064 atexit(SignalHandler::delete_instance);
00065 }
00066
00068 void
00069 SignalHandler::delete_instance()
00070 {
00071 if (SignalHandler::d_instance) {
00072 for (int i = 0; i < NSIG; ++i) {
00073
00074
00075
00076
00077 d_signal_handlers[i] = 0;
00078 d_old_handlers[i] = 0;
00079 }
00080
00081 delete SignalHandler::d_instance;
00082 SignalHandler::d_instance = 0;
00083 }
00084 }
00085
00092 void
00093 SignalHandler::dispatcher(int signum)
00094 {
00095
00096 if (SignalHandler::d_signal_handlers[signum] != 0)
00097
00098 SignalHandler::d_signal_handlers[signum]->handle_signal(signum);
00099
00100 Sigfunc *old_handler = SignalHandler::d_old_handlers[signum];
00101 if (old_handler == SIG_IGN || old_handler == SIG_ERR)
00102 return;
00103 else if (old_handler == SIG_DFL) {
00104 switch (signum) {
00105 #ifndef WIN32
00106 case SIGHUP:
00107 case SIGKILL:
00108 case SIGUSR1:
00109 case SIGUSR2:
00110 case SIGPIPE:
00111 case SIGALRM:
00112 #endif
00113 case SIGINT:
00114 case SIGTERM: _exit(EXIT_FAILURE);
00115
00116
00117
00118 default: abort();
00119 }
00120 }
00121 else
00122 old_handler(signum);
00123 }
00124
00126 SignalHandler*
00127 SignalHandler::instance()
00128 {
00129 pthread_once(&instance_control, initialize_instance);
00130
00131 return d_instance;
00132 }
00133
00146 EventHandler *
00147 SignalHandler::register_handler(int signum, EventHandler *eh, bool override)
00148 {
00149
00150 switch (signum) {
00151 #ifndef WIN32
00152 case SIGHUP:
00153 case SIGKILL:
00154 case SIGUSR1:
00155 case SIGUSR2:
00156 case SIGPIPE:
00157 case SIGALRM:
00158 #endif
00159 case SIGINT:
00160 case SIGTERM: break;
00161
00162 default: throw InternalErr(__FILE__, __LINE__,
00163 string("Call to register_handler with unsupported signal (")
00164 + long_to_string(signum) + string(")."));
00165 }
00166
00167
00168 EventHandler *old_eh = SignalHandler::d_signal_handlers[signum];
00169
00170 SignalHandler::d_signal_handlers[signum] = eh;
00171
00172
00173
00174 #ifndef WIN32
00175 struct sigaction sa;
00176 sa.sa_handler = dispatcher;
00177 sigemptyset(&sa.sa_mask);
00178 sa.sa_flags = 0;
00179
00180
00181
00182
00183 if (signum == SIGALRM) {
00184 #ifdef SA_INTERUPT
00185 sa.sa_flags |= SA_INTERUPT;
00186 #endif
00187 }
00188 else {
00189 #ifdef SA_RESTART
00190 sa.sa_flags |= SA_RESTART;
00191 #endif
00192 }
00193
00194 struct sigaction osa;
00195
00196 if (sigaction(signum, &sa, &osa) < 0)
00197 throw InternalErr(__FILE__, __LINE__, "Could not register a signal handler.");
00198
00199
00200
00201
00202
00203 if (override)
00204 SignalHandler::d_old_handlers[signum] = SIG_IGN;
00205 else if (osa.sa_handler != dispatcher)
00206 SignalHandler::d_old_handlers[signum] = osa.sa_handler;
00207 #endif
00208
00209 return old_eh;
00210 }
00211
00215 EventHandler *
00216 SignalHandler::remove_handler(int signum)
00217 {
00218 EventHandler *old_eh = SignalHandler::d_signal_handlers[signum];
00219
00220 SignalHandler::d_signal_handlers[signum] = 0;
00221
00222 return old_eh;
00223 }
00224
00225 }