00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "assa/SigHandlers.h"
00013
00014 using namespace ASSA;
00015
00016 #if !defined(WIN32)
00017
00018
00019
00020
00021
00022 SigHandlersList* SigHandlersList::m_instance[NSIG];
00023
00024 void
00025 SigHandlers::
00026 sighandlers_dispatcher (int signum_)
00027 {
00028 trace_with_mask("SigHandlers::sighandlers_dispatch", SIGHAND);
00029
00030 DL((SIGHAND,"==> Recevied signal # %d\n", signum_));
00031 dispatch (signum_);
00032 }
00033
00034 int
00035 SigHandlers::
00036 install (int signum_,
00037 EventHandler* new_hand_,
00038 SigAction* new_disp_,
00039 EventHandler** old_hand_,
00040 SigAction* old_disp_)
00041 {
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 trace_with_mask("SigHandlers::install()", SIGHAND);
00052
00053 if (!in_range(signum_) == -1) {
00054 EL((ASSAERR,"in_range (%s) failed\n",signum_));
00055 return -1;
00056 }
00057
00058 CFUNC_Handler* cfhp = NULL;
00059 SigHandlersList* handlist = NULL;
00060
00061 handlist = SigHandlersList::instance(signum_);
00062
00063
00064
00065 SigAction cd;
00066 cd.retrieve_action(signum_);
00067
00068
00069
00070
00071
00072 if ( cd.handler() != (C_SIG_HANDLER) sighandlers_dispatcher &&
00073 cd.handler() != SIG_IGN &&
00074 cd.handler() != SIG_DFL )
00075 {
00076
00077
00078
00079
00080
00081
00082
00083
00084 DL((SIGHAND,"Detected 3rd party \"C\" handler!\n"));
00085
00086 cfhp = new CFUNC_Handler (cd.handler ());
00087 handlist->cfunc_handler (cfhp);
00088
00089
00090
00091
00092
00093 DL((SIGHAND,"Adding 3rd party \"C\" handler\n"));
00094
00095 if ( handlist->insert (cfhp) == false ) {
00096 EL((ASSAERR, "Failed to insert "\
00097 "c_func_handler for signum %d\n", signum_));
00098 delete (cfhp);
00099 handlist->cfunc_handler (0);
00100 return -1;
00101 }
00102 DL((SIGHAND,"Set size: %d\n", handlist->size () ));
00103 }
00104
00105
00106 DL((SIGHAND,"Adding EventHandler to the list\n"));
00107
00108 if (handlist->insert (new_hand_) == false) {
00109
00110
00111
00112
00113
00114 EL((ASSAERR,"failed to add new_hand_ to handlers list\n"));
00115
00116 if (handlist->seen_cfunc_handler () &&
00117 handlist->size() == 1)
00118 {
00119 handlist->erase ();
00120 handlist->cfunc_handler (0);
00121 }
00122 return -1;
00123 }
00124 DL((SIGHAND,"Set size: %d\n", handlist->size () ));
00125
00126
00127
00128 if (cd.handler() == (C_SIG_HANDLER) sighandlers_dispatcher) {
00129 return 0;
00130 }
00131 DL((SIGHAND,"Installing 'sighandlers_dispatcher'\n"));
00132
00133
00134
00135
00136
00137 SigAction sa ((C_SIG_HANDLER) SIG_DFL);
00138
00139 if (new_disp_ == 0) {
00140 new_disp_ = &sa;
00141 }
00142
00143 new_disp_->handler ((C_SIG_HANDLER) sighandlers_dispatcher);
00144
00145 if (new_disp_->register_action (signum_, old_disp_) == -1) {
00146
00147
00148
00149
00150
00151
00152 EL((ASSAERR,"register_action() error\n"));
00153
00154 if (handlist->seen_cfunc_handler ()) {
00155 handlist->erase ();
00156 handlist->cfunc_handler (0);
00157 delete cfhp;
00158 }
00159 handlist->erase (new_hand_);
00160 return -1;
00161 }
00162 return 0;
00163 }
00164
00165 int
00166 SigHandlers::
00167 remove (int signum_, EventHandler* eh_,
00168 SigAction* new_disp_, SigAction* old_disp_)
00169
00170 {
00171 trace_with_mask("SigHandlers::remove()", SIGHAND);
00172
00173 if (in_range (signum_)) {
00174 EL((ASSAERR, "singum_ %d is out of range\n", signum_));
00175 return -1;
00176 }
00177
00178 CFUNC_Handler* Cfhp = NULL;
00179 EventHandler* ehp = NULL;
00180
00181 SigHandlersList& handlist = *(SigHandlersList::instance(signum_));
00182
00183 if (eh_ == NULL) {
00184 DL((SIGHAND,"Erasing the entire set\n"));
00185
00186 handlist.erase ();
00187 DL((SIGHAND,"Set size: %d\n", handlist.size ()));
00188 }
00189 else {
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 SigHandlersList::iterator it;
00205
00206 if ((it = handlist.find (eh_)) != handlist.end ()) {
00207 DL((SIGHAND,"Removing EventHandler\n"));
00208 ehp = (*it);
00209 handlist.erase (it);
00210 }
00211 DL((SIGHAND,"Set size: %d\n", handlist.size () ));
00212 }
00213
00214 if (handlist.size ()) return 0;
00215
00216
00217
00218
00219 SigAction null_sa;
00220 if (new_disp_ == 0) new_disp_ = &null_sa;
00221
00222 DL((SIGHAND,"Handlers List is empty\n"));
00223
00224 if (handlist.seen_cfunc_handler ()) {
00225
00226 DL((SIGHAND,"Reinstalling \"C\" handler\n"));
00227 Cfhp = handlist.cfunc_handler (0);
00228 new_disp_->handler (Cfhp->handler ());
00229 delete Cfhp;
00230 }
00231
00232 return new_disp_->register_action (signum_, old_disp_);
00233 }
00234
00235 void
00236 SigHandlers::
00237 dispatch (int signum_)
00238 {
00239 trace_with_mask("SigHandlers::dispatch", SIGHAND);
00240
00241
00242
00243
00244
00245
00246
00247 int errno_saved = errno;
00248
00249 SigHandlersList& handlist = *(SigHandlersList::instance(signum_));
00250 SigHandlersList::iterator it;
00251 EventHandler* ehp;
00252
00253 for (it=handlist.begin(); it != handlist.end(); it++) {
00254 ehp = *it;
00255 if (ehp->handle_signal (signum_) == -1) {
00256
00257
00258
00259
00260 handlist.erase (it);
00261 }
00262 }
00263
00264 errno = errno_saved;
00265 }
00266
00267 #endif // !defined(WIN32)
00268