/home/vlg/develop/libASSA/libassa/assa/SigHandler.cpp

Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //---------------------------------------------------------------------------
00003 //                            SigHandler.cpp
00004 //---------------------------------------------------------------------------
00005 //  Copyright (C) 1997-2002  Vladislav Grinchenko 
00006 //
00007 //  This library is free software; you can redistribute it and/or
00008 //  modify it under the terms of the GNU Library General Public
00009 //  License as published by the Free Software Foundation; either
00010 //  version 2 of the License, or (at your option) any later version.
00011 //---------------------------------------------------------------------------
00012 #include <signal.h>
00013 
00014 #include "assa/Assure.h"
00015 #include "assa/SigHandler.h"
00016 
00017 using namespace ASSA;
00018 
00019 #if !defined(WIN32)
00020 
00021 /*--- static variables ---*/
00022 
00023 EventHandler* SigHandler::m_signal_handlers [NSIG];
00024 
00025 int
00026 SigHandler::
00027 in_range (int signum_)
00028 {
00029     trace_with_mask("SigHandler::in_range", SIGHAND);
00030 
00031     if ( signum_ >= 1 && signum_ < NSIG) {
00032         return 0;
00033     }
00034     else {
00035         DL((SIGHAND,"signum_ %d is out of range [1;%d]\n", NSIG));
00036         return -1;
00037     }
00038 }
00039 
00040 EventHandler *
00041 SigHandler::
00042 handler (int signum_, EventHandler* newh_)
00043 {
00044     trace_with_mask("SigHandler::handler(int, EH*)", SIGHAND);
00045     
00046 
00047     if (in_range(signum_) == -1)
00048         return 0;
00049 
00050     EventHandler* oh = m_signal_handlers[signum_];
00051     m_signal_handlers[signum_] = newh_;
00052 
00053     return oh;
00054 }
00055 
00056 EventHandler *
00057 SigHandler::
00058 handler (int signum_)
00059 {
00060     trace_with_mask("SigHandler::handler", SIGHAND);
00061 
00062     if ( in_range (signum_) == -1 ) 
00063         return 0;
00064 
00065     return m_signal_handlers[signum_];
00066 }
00067 
00068 int 
00069 SigHandler::
00070 install (int signum_, EventHandler *new_hand_, SigAction *new_disp_,
00071          EventHandler **old_hand_, SigAction *old_disp_)
00072 {
00073     trace_with_mask("SigHandler::install", SIGHAND);
00074 
00075     if (in_range (signum_) == -1) 
00076         return -1;
00077 
00078     /*--- replace old Event Handler ptr with new one in my internal 
00079       dispatch table, returning the old one.
00080       ---*/
00081     EventHandler* eh = handler(signum_, new_hand_);
00082     
00083     /*--- if I am given place to store, save old handler ---*/
00084     if (old_hand_ != 0) 
00085         *old_hand_ = eh;
00086     
00087     /*--- retrieve old disposition ---*/
00088     if (old_disp_ != 0) {
00089         old_disp_->retrieve_action (signum_);
00090         old_disp_->handler ((C_SIG_HANDLER) SIG_DFL);
00091     }
00092     
00093     /*--- if new disposition is NULL, use null action instead ---*/
00094     SigAction null_sa;  
00095     
00096     if (new_disp_ == 0) 
00097         new_disp_ = &null_sa;
00098     
00099     /*--- install my dispatcher ---*/
00100     new_disp_->handler((C_SIG_HANDLER) SigHandler::dispatch);
00101     
00102     return new_disp_->register_action(signum_, old_disp_);
00103 }
00104 
00105 int
00106 SigHandler::
00107 remove (int signum_, EventHandler* /* eh_ */,
00108         SigAction *new_disp_,  SigAction *old_disp_)
00109 {
00110     trace_with_mask("SigHandler::remove", SIGHAND);
00111 
00112     if (in_range(signum_) == -1) 
00113         return -1;
00114     /*--- 
00115       We need default disposition here if user forgot to give us one.
00116       ---*/
00117     SigAction sa ((C_SIG_HANDLER) SIG_DFL);
00118 
00119     if (new_disp_ == 0) {
00120         new_disp_ = &sa;
00121     }
00122 
00123     m_signal_handlers[signum_] = 0;
00124     
00125     return new_disp_->register_action (signum_, old_disp_);
00126 }
00127 
00128 void 
00129 SigHandler::
00130 dispatch (int signum_)
00131 {
00132     trace_with_mask("SigHandler::dispatch", SIGHAND);
00133   
00134     /*--- save errno ---*/
00135     int my_errno = errno;
00136 
00137     EventHandler *eh = m_signal_handlers[signum_];
00138 
00139     if (eh != 0 && eh->handle_signal(signum_) == -1) {
00140         /*--- 
00141           we are in trouble, fall back to defaults 
00142           ---*/
00143         SigAction defact((C_SIG_HANDLER) SIG_DFL);
00144         m_signal_handlers[signum_] = 0;
00145         defact.register_action(signum_);
00146     }
00147     /*--- restore errno ---*/
00148     errno = my_errno;
00149 }
00150 
00151 #endif // !defined(WIN32)
00152 

Generated on Sun Aug 13 15:08:00 2006 for libassa by  doxygen 1.4.6