libassa  3.5.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
SigHandler.cpp
Go to the documentation of this file.
1 // -*- c++ -*-
2 //---------------------------------------------------------------------------
3 // SigHandler.cpp
4 //---------------------------------------------------------------------------
5 // Copyright (C) 1997-2002 Vladislav Grinchenko
6 //
7 // This library is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Library General Public
9 // License as published by the Free Software Foundation; either
10 // version 2 of the License, or (at your option) any later version.
11 //---------------------------------------------------------------------------
12 #include <signal.h>
13 
14 #include "assa/Assure.h"
15 #include "assa/SigHandler.h"
16 
17 using namespace ASSA;
18 
19 #if !defined(WIN32)
20 
21 /*--- static variables ---*/
22 
24 
25 int
27 in_range (int signum_)
28 {
29  trace_with_mask("SigHandler::in_range", SIGHAND);
30 
31  if ( signum_ >= 1 && signum_ < NSIG) {
32  return 0;
33  }
34  else {
35  DL((SIGHAND,"signum_ %d is out of range [1;%d]\n", NSIG));
36  return -1;
37  }
38 }
39 
42 handler (int signum_, EventHandler* newh_)
43 {
44  trace_with_mask("SigHandler::handler(int, EH*)", SIGHAND);
45 
46 
47  if (in_range(signum_) == -1)
48  return 0;
49 
50  EventHandler* oh = m_signal_handlers[signum_];
51  m_signal_handlers[signum_] = newh_;
52 
53  return oh;
54 }
55 
58 handler (int signum_)
59 {
60  trace_with_mask("SigHandler::handler", SIGHAND);
61 
62  if ( in_range (signum_) == -1 )
63  return 0;
64 
65  return m_signal_handlers[signum_];
66 }
67 
68 int
70 install (int signum_, EventHandler *new_hand_, SigAction *new_disp_,
71  EventHandler **old_hand_, SigAction *old_disp_)
72 {
73  trace_with_mask("SigHandler::install", SIGHAND);
74 
75  if (in_range (signum_) == -1)
76  return -1;
77 
78  /*--- replace old Event Handler ptr with new one in my internal
79  dispatch table, returning the old one.
80  ---*/
81  EventHandler* eh = handler(signum_, new_hand_);
82 
83  /*--- if I am given place to store, save old handler ---*/
84  if (old_hand_ != 0)
85  *old_hand_ = eh;
86 
87  /*--- retrieve old disposition ---*/
88  if (old_disp_ != 0) {
89  old_disp_->retrieve_action (signum_);
90  old_disp_->handler ((C_SIG_HANDLER) SIG_DFL);
91  }
92 
93  /*--- if new disposition is NULL, use null action instead ---*/
94  SigAction null_sa;
95 
96  if (new_disp_ == 0)
97  new_disp_ = &null_sa;
98 
99  /*--- install my dispatcher ---*/
101 
102  return new_disp_->register_action(signum_, old_disp_);
103 }
104 
105 int
107 remove (int signum_, EventHandler* /* eh_ */,
108  SigAction *new_disp_, SigAction *old_disp_)
109 {
110  trace_with_mask("SigHandler::remove", SIGHAND);
111 
112  if (in_range(signum_) == -1)
113  return -1;
114  /*---
115  We need default disposition here if user forgot to give us one.
116  ---*/
117  SigAction sa ((C_SIG_HANDLER) SIG_DFL);
118 
119  if (new_disp_ == 0) {
120  new_disp_ = &sa;
121  }
122 
123  m_signal_handlers[signum_] = 0;
124 
125  return new_disp_->register_action (signum_, old_disp_);
126 }
127 
128 void
130 dispatch (int signum_)
131 {
132  trace_with_mask("SigHandler::dispatch", SIGHAND);
133 
134  /*--- save errno ---*/
135  int my_errno = errno;
136 
137  EventHandler *eh = m_signal_handlers[signum_];
138 
139  if (eh != 0 && eh->handle_signal(signum_) == -1) {
140  /*---
141  we are in trouble, fall back to defaults
142  ---*/
143  SigAction defact((C_SIG_HANDLER) SIG_DFL);
144  m_signal_handlers[signum_] = 0;
145  defact.register_action(signum_);
146  }
147  /*--- restore errno ---*/
148  errno = my_errno;
149 }
150 
151 #endif // !defined(WIN32)
152