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 /*--- static variables ---*/
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     /*--- replace old Event Handler ptr with new one in my internal 
00077       dispatch table, returning the old one.
00078       ---*/
00079     EventHandler* eh = handler(signum_, new_hand_);
00080     
00081     /*--- if I am given place to store, save old handler ---*/
00082     if (old_hand_ != 0) 
00083         *old_hand_ = eh;
00084     
00085     /*--- retrieve old disposition ---*/
00086     if (old_disp_ != 0) {
00087         old_disp_->retrieve_action (signum_);
00088         old_disp_->handler ((C_SIG_HANDLER) SIG_DFL);
00089     }
00090     
00091     /*--- if new disposition is NULL, use null action instead ---*/
00092     SigAction null_sa;  
00093     
00094     if (new_disp_ == 0) 
00095         new_disp_ = &null_sa;
00096     
00097     /*--- install my dispatcher ---*/
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* /* eh_ */,
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       We need default disposition here if user forgot to give us one.
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     /*--- save errno ---*/
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           we are in trouble, fall back to defaults 
00140           ---*/
00141         SigAction defact((C_SIG_HANDLER) SIG_DFL);
00142         m_signal_handlers[signum_] = 0;
00143         defact.register_action(signum_);
00144     }
00145     /*--- restore errno ---*/
00146     errno = my_errno;
00147 }

Generated on Mon Dec 19 15:55:15 2005 for libassa by  doxygen 1.4.5