00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <signal.h>
00013
00014 #include "assa/Assure.h"
00015 #include "assa/SigHandler.h"
00016
00017 using namespace ASSA;
00018
00019
00020
00021 EventHandler* SigHandler::m_signal_handlers [NSIG];
00022
00023 int
00024 SigHandler::
00025 in_range (int signum_)
00026 {
00027 trace_with_mask("SigHandler::in_range", SIGHAND);
00028
00029 if ( signum_ >= 1 && signum_ < NSIG) {
00030 return 0;
00031 }
00032 else {
00033 DL((SIGHAND,"signum_ %d is out of range [1;%d]\n", NSIG));
00034 return -1;
00035 }
00036 }
00037
00038 EventHandler *
00039 SigHandler::
00040 handler (int signum_, EventHandler* newh_)
00041 {
00042 trace_with_mask("SigHandler::handler(int, EH*)", SIGHAND);
00043
00044
00045 if (in_range(signum_) == -1)
00046 return 0;
00047
00048 EventHandler* oh = m_signal_handlers[signum_];
00049 m_signal_handlers[signum_] = newh_;
00050
00051 return oh;
00052 }
00053
00054 EventHandler *
00055 SigHandler::
00056 handler (int signum_)
00057 {
00058 trace_with_mask("SigHandler::handler", SIGHAND);
00059
00060 if ( in_range (signum_) == -1 )
00061 return 0;
00062
00063 return m_signal_handlers[signum_];
00064 }
00065
00066 int
00067 SigHandler::
00068 install (int signum_, EventHandler *new_hand_, SigAction *new_disp_,
00069 EventHandler **old_hand_, SigAction *old_disp_)
00070 {
00071 trace_with_mask("SigHandler::install", SIGHAND);
00072
00073 if (in_range (signum_) == -1)
00074 return -1;
00075
00076
00077
00078
00079 EventHandler* eh = handler(signum_, new_hand_);
00080
00081
00082 if (old_hand_ != 0)
00083 *old_hand_ = eh;
00084
00085
00086 if (old_disp_ != 0) {
00087 old_disp_->retrieve_action (signum_);
00088 old_disp_->handler ((C_SIG_HANDLER) SIG_DFL);
00089 }
00090
00091
00092 SigAction null_sa;
00093
00094 if (new_disp_ == 0)
00095 new_disp_ = &null_sa;
00096
00097
00098 new_disp_->handler((C_SIG_HANDLER) SigHandler::dispatch);
00099
00100 return new_disp_->register_action(signum_, old_disp_);
00101 }
00102
00103 int
00104 SigHandler::
00105 remove (int signum_, EventHandler* ,
00106 SigAction *new_disp_, SigAction *old_disp_)
00107 {
00108 trace_with_mask("SigHandler::remove", SIGHAND);
00109
00110 if (in_range(signum_) == -1)
00111 return -1;
00112
00113
00114
00115 SigAction sa ((C_SIG_HANDLER) SIG_DFL);
00116
00117 if (new_disp_ == 0) {
00118 new_disp_ = &sa;
00119 }
00120
00121 m_signal_handlers[signum_] = 0;
00122
00123 return new_disp_->register_action (signum_, old_disp_);
00124 }
00125
00126 void
00127 SigHandler::
00128 dispatch (int signum_)
00129 {
00130 trace_with_mask("SigHandler::dispatch", SIGHAND);
00131
00132
00133 int my_errno = errno;
00134
00135 EventHandler *eh = m_signal_handlers[signum_];
00136
00137 if (eh != 0 && eh->handle_signal(signum_) == -1) {
00138
00139
00140
00141 SigAction defact((C_SIG_HANDLER) SIG_DFL);
00142 m_signal_handlers[signum_] = 0;
00143 defact.register_action(signum_);
00144 }
00145
00146 errno = my_errno;
00147 }