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 22703 2010-05-11 18:10:01Z jimg $"
00036 };
00037
00038 #include <cstdlib>
00039
00040 #include <signal.h>
00041 #include <pthread.h>
00042
00043 #ifdef HAVE_UNISTD_H
00044 #include <unistd.h>
00045 #endif
00046
00047 #include "SignalHandler.h"
00048 #include "util.h"
00049
00050 namespace libdap {
00051
00052 EventHandler *SignalHandler::d_signal_handlers[NSIG];
00053 Sigfunc *SignalHandler::d_old_handlers[NSIG];
00054 SignalHandler *SignalHandler::d_instance = 0;
00055
00056
00057
00058 static pthread_once_t instance_control = PTHREAD_ONCE_INIT;
00059
00061 void
00062 SignalHandler::initialize_instance()
00063 {
00064
00065 SignalHandler::d_instance = new SignalHandler;
00066 atexit(SignalHandler::delete_instance);
00067 }
00068
00070 void
00071 SignalHandler::delete_instance()
00072 {
00073 if (SignalHandler::d_instance) {
00074 for (int i = 0; i < NSIG; ++i) {
00075
00076
00077
00078
00079 d_signal_handlers[i] = 0;
00080 d_old_handlers[i] = 0;
00081 }
00082
00083 delete SignalHandler::d_instance;
00084 SignalHandler::d_instance = 0;
00085 }
00086 }
00087
00094 void
00095 SignalHandler::dispatcher(int signum)
00096 {
00097
00098 if (SignalHandler::d_signal_handlers[signum] != 0)
00099
00100 SignalHandler::d_signal_handlers[signum]->handle_signal(signum);
00101
00102 Sigfunc *old_handler = SignalHandler::d_old_handlers[signum];
00103 if (old_handler == SIG_IGN || old_handler == SIG_ERR)
00104 return;
00105 else if (old_handler == SIG_DFL) {
00106 switch (signum) {
00107 #ifndef WIN32
00108 case SIGHUP:
00109 case SIGKILL:
00110 case SIGUSR1:
00111 case SIGUSR2:
00112 case SIGPIPE:
00113 case SIGALRM:
00114 #endif
00115 case SIGINT:
00116 case SIGTERM: _exit(EXIT_FAILURE);
00117
00118
00119
00120 default: abort();
00121 }
00122 }
00123 else
00124 old_handler(signum);
00125 }
00126
00128 SignalHandler*
00129 SignalHandler::instance()
00130 {
00131 pthread_once(&instance_control, initialize_instance);
00132
00133 return d_instance;
00134 }
00135
00148 EventHandler *
00149 SignalHandler::register_handler(int signum, EventHandler *eh, bool override)
00150 {
00151
00152 switch (signum) {
00153 #ifndef WIN32
00154 case SIGHUP:
00155 case SIGKILL:
00156 case SIGUSR1:
00157 case SIGUSR2:
00158 case SIGPIPE:
00159 case SIGALRM:
00160 #endif
00161 case SIGINT:
00162 case SIGTERM: break;
00163
00164 default: throw InternalErr(__FILE__, __LINE__,
00165 string("Call to register_handler with unsupported signal (")
00166 + long_to_string(signum) + string(")."));
00167 }
00168
00169
00170 EventHandler *old_eh = SignalHandler::d_signal_handlers[signum];
00171
00172 SignalHandler::d_signal_handlers[signum] = eh;
00173
00174
00175
00176 #ifndef WIN32
00177 struct sigaction sa;
00178 sa.sa_handler = dispatcher;
00179 sigemptyset(&sa.sa_mask);
00180 sa.sa_flags = 0;
00181
00182
00183
00184
00185 if (signum == SIGALRM) {
00186 #ifdef SA_INTERUPT
00187 sa.sa_flags |= SA_INTERUPT;
00188 #endif
00189 }
00190 else {
00191 #ifdef SA_RESTART
00192 sa.sa_flags |= SA_RESTART;
00193 #endif
00194 }
00195
00196 struct sigaction osa;
00197
00198 if (sigaction(signum, &sa, &osa) < 0)
00199 throw InternalErr(__FILE__, __LINE__, "Could not register a signal handler.");
00200
00201
00202
00203
00204
00205 if (override)
00206 SignalHandler::d_old_handlers[signum] = SIG_IGN;
00207 else if (osa.sa_handler != dispatcher)
00208 SignalHandler::d_old_handlers[signum] = osa.sa_handler;
00209 #endif
00210
00211 return old_eh;
00212 }
00213
00217 EventHandler *
00218 SignalHandler::remove_handler(int signum)
00219 {
00220 EventHandler *old_eh = SignalHandler::d_signal_handlers[signum];
00221
00222 SignalHandler::d_signal_handlers[signum] = 0;
00223
00224 return old_eh;
00225 }
00226
00227 }