00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Signal.h 00006 * 00007 * Signal.h,v 4.53 2006/02/23 09:00:18 jwillemsen Exp 00008 * 00009 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> 00010 */ 00011 //============================================================================= 00012 00013 #ifndef ACE_SIGNAL_HANDLER_H 00014 #define ACE_SIGNAL_HANDLER_H 00015 #include /**/ "ace/pre.h" 00016 00017 #include "ace/config-lite.h" 00018 00019 #if defined (ACE_DONT_INCLUDE_ACE_SIGNAL_H) 00020 # error ace/Signal.h was #included instead of signal.h by ace/OS_NS_signal.h: fix!!!! 00021 #endif /* ACE_DONT_INCLUDE_ACE_SIGNAL_H */ 00022 00023 #include "ace/ACE_export.h" 00024 00025 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00026 # pragma once 00027 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00028 00029 #include "ace/os_include/os_signal.h" 00030 #include "ace/Event_Handler.h" 00031 00032 // Type of the extended signal handler. 00033 typedef void (*ACE_Sig_Handler_Ex) (int, siginfo_t *siginfo, ucontext_t *ucontext); 00034 00035 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00036 00037 /** 00038 * @class ACE_Sig_Set 00039 * 00040 * @brief Provide a C++ wrapper for the C sigset_t interface. 00041 * 00042 * Handle signals via a more elegant C++ interface (e.g., 00043 * doesn't require the use of global variables or global 00044 * functions in an application). 00045 */ 00046 class ACE_Export ACE_Sig_Set 00047 { 00048 public: 00049 // = Initialization and termination methods. 00050 /// Initialize <sigset_> with @a sigset. If @a sigset == 0 then fill 00051 /// the set. 00052 ACE_Sig_Set (sigset_t *sigset); 00053 00054 /// Initialize <sigset_> with @a sigset. If @a sigset == 0 then fill 00055 /// the set. 00056 ACE_Sig_Set (ACE_Sig_Set *sigset); 00057 00058 /// If @a fill == 0 then initialize the <sigset_> to be empty, else 00059 /// full. 00060 ACE_Sig_Set (int fill = 0); 00061 00062 ~ACE_Sig_Set (void); 00063 00064 /// Create a set that excludes all signals defined by the system. 00065 int empty_set (void); 00066 00067 /// Create a set that includes all signals defined by the system. 00068 int fill_set (void); 00069 00070 /// Adds the individual signal specified by <signo> to the set. 00071 int sig_add (int signo); 00072 00073 /// Deletes the individual signal specified by <signo> from the set. 00074 int sig_del (int signo); 00075 00076 /// Checks whether the signal specified by <signo> is in the set. 00077 int is_member (int signo) const; 00078 00079 /// Returns a pointer to the underlying <sigset_t>. 00080 operator sigset_t *(); 00081 00082 /// Returns a copy of the underlying <sigset_t>. 00083 sigset_t sigset (void) const; 00084 00085 /// Dump the state of an object. 00086 void dump (void) const; 00087 00088 /// Declare the dynamic allocation hooks. 00089 ACE_ALLOC_HOOK_DECLARE; 00090 00091 private: 00092 /// Set of signals. 00093 sigset_t sigset_; 00094 }; 00095 00096 /** 00097 * @class ACE_Sig_Action 00098 * 00099 * @brief C++ wrapper facade for the <sigaction> struct. 00100 */ 00101 class ACE_Export ACE_Sig_Action 00102 { 00103 public: 00104 // = Initialization methods. 00105 /// Default constructor. Initializes everything to 0. 00106 ACE_Sig_Action (void); 00107 00108 /// Assigns the various fields of a <sigaction> struct but doesn't 00109 /// register for signal handling via the <sigaction> function. 00110 ACE_Sig_Action (ACE_SignalHandler handler, 00111 sigset_t *sigmask = 0, 00112 int flags = 0); 00113 00114 /// Assigns the various fields of a <sigaction> struct but doesn't 00115 /// register for signal handling via the <sigaction> function. 00116 ACE_Sig_Action (ACE_SignalHandler handler, 00117 const ACE_Sig_Set &sigmask, 00118 int flags = 0); 00119 00120 /** 00121 * Assigns the various fields of a <sigaction> struct and registers 00122 * the <handler> to process signal <signum> via the <sigaction> 00123 * function. 00124 */ 00125 ACE_Sig_Action (ACE_SignalHandler handler, 00126 int signum, 00127 sigset_t *sigmask = 0, 00128 int flags = 0); 00129 00130 /** 00131 * Assigns the various fields of a <sigaction> struct and registers 00132 * the <handler> to process signal <signum> via the <sigaction> 00133 * function. 00134 */ 00135 ACE_Sig_Action (ACE_SignalHandler handler, 00136 int signum, 00137 const ACE_Sig_Set &sigmask, 00138 int flags = 0); 00139 00140 00141 // @@ The next two methods have a parameter as "signalss". Please do 00142 // not change the argument name as "signals". This causes the 00143 // following problem as reported by 00144 // <James.Briggs@dsto.defence.gov.au>. 00145 00146 // In the file Signal.h two of the functions have and argument name 00147 // of signals. signals is a Qt macro (to do with their meta object 00148 // stuff. 00149 // We could as well have it as "signal", but I am nost sure whether 00150 // that would cause a problem with something else - Bala <bala@cs> 00151 00152 /** 00153 * Assigns the various fields of a <sigaction> struct and registers 00154 * the <handler> to process all <signals> via the <sigaction> 00155 * function. 00156 */ 00157 ACE_Sig_Action (const ACE_Sig_Set &signalss, 00158 ACE_SignalHandler handler, 00159 const ACE_Sig_Set &sigmask, 00160 int flags = 0); 00161 00162 /** 00163 * Assigns the various fields of a <sigaction> struct and registers 00164 * the <handler> to process all <signals> via the <sigaction> 00165 * function. 00166 */ 00167 ACE_Sig_Action (const ACE_Sig_Set &signalss, 00168 ACE_SignalHandler handler, 00169 sigset_t *sigmask = 0, 00170 int flags = 0); 00171 00172 /// Copy constructor. 00173 ACE_Sig_Action (const ACE_Sig_Action &s); 00174 00175 /// Default dtor. 00176 ~ACE_Sig_Action (void); 00177 00178 // = Signal action management. 00179 /// Register <this> as the current disposition and store old 00180 /// disposition into <oaction> if it is non-NULL. 00181 int register_action (int signum, 00182 ACE_Sig_Action *oaction = 0); 00183 00184 /// Assign the value of <oaction> to <this> and make it become the 00185 /// new signal disposition. 00186 int restore_action (int signum, 00187 ACE_Sig_Action &oaction); 00188 00189 /// Retrieve the current disposition into <this>. 00190 int retrieve_action (int signum); 00191 00192 /// Set current signal action. 00193 void set (struct sigaction *); 00194 00195 /// Get current signal action. 00196 struct sigaction *get (void); 00197 operator struct sigaction *(); 00198 00199 /// Set current signal flags. 00200 void flags (int); 00201 00202 /// Get current signal flags. 00203 int flags (void); 00204 00205 /// Set current signal mask. 00206 void mask (sigset_t *); 00207 void mask (ACE_Sig_Set &); 00208 00209 /// Get current signal mask. 00210 sigset_t *mask (void); 00211 00212 /// Set current signal handler (pointer to function). 00213 void handler (ACE_SignalHandler); 00214 00215 /// Get current signal handler (pointer to function). 00216 ACE_SignalHandler handler (void); 00217 00218 /// Dump the state of an object. 00219 void dump (void) const; 00220 00221 /// Declare the dynamic allocation hooks. 00222 ACE_ALLOC_HOOK_DECLARE; 00223 00224 private: 00225 /// Controls signal behavior. 00226 struct sigaction sa_; 00227 }; 00228 00229 /** 00230 * @class ACE_Sig_Guard 00231 * 00232 * @brief Hold signals in MASK for duration of a C++ statement block. 00233 * Note that a "0" for mask causes all signals to be held. 00234 */ 00235 class ACE_Export ACE_Sig_Guard 00236 { 00237 public: 00238 // = Initialization and termination methods. 00239 /// This is kind of conditional Guard, needed when guard should be 00240 /// activated only when a spcific condition met. When condition == 00241 /// true (default), Guard is activated 00242 ACE_Sig_Guard (ACE_Sig_Set *mask = 0, bool condition = true); 00243 00244 /// Restore blocked signals. 00245 ~ACE_Sig_Guard (void); 00246 00247 /// Dump the state of an object. 00248 void dump (void) const; 00249 00250 /// Declare the dynamic allocation hooks. 00251 ACE_ALLOC_HOOK_DECLARE; 00252 00253 private: 00254 /// Original signal mask. 00255 ACE_Sig_Set omask_; 00256 00257 /// Guard Condition 00258 bool condition_; 00259 }; 00260 00261 /** 00262 * @class ACE_Sig_Handler 00263 * 00264 * @brief This is the main dispatcher of signals for ACE. It improves 00265 * the existing UNIX signal handling mechanism by allowing C++ 00266 * objects to handle signals in a way that avoids the use of 00267 * global/static variables and functions. 00268 * 00269 * Using this class a program can register an ACE_Event_Handler 00270 * with the ACE_Sig_Handler in order to handle a designated 00271 * <signum>. When a signal occurs that corresponds to this 00272 * <signum>, the <handle_signal> method of the registered 00273 * ACE_Event_Handler is invoked automatically. 00274 */ 00275 class ACE_Export ACE_Sig_Handler 00276 { 00277 public: 00278 /// Default ctor/dtor. 00279 ACE_Sig_Handler (void); 00280 virtual ~ACE_Sig_Handler (void); 00281 00282 // = Registration and removal methods. 00283 /** 00284 * Add a new ACE_Event_Handler and a new sigaction associated with 00285 * <signum>. Passes back the existing ACE_Event_Handler and its 00286 * sigaction if pointers are non-zero. Returns -1 on failure and >= 00287 * 0 on success. 00288 */ 00289 virtual int register_handler (int signum, 00290 ACE_Event_Handler *new_sh, 00291 ACE_Sig_Action *new_disp = 0, 00292 ACE_Event_Handler **old_sh = 0, 00293 ACE_Sig_Action *old_disp = 0); 00294 00295 /** 00296 * Remove the ACE_Event_Handler currently associated with 00297 * <signum>. <sigkey> is ignored in this implementation since there 00298 * is only one instance of a signal handler. Install the new 00299 * disposition (if given) and return the previous disposition (if 00300 * desired by the caller). Returns 0 on success and -1 if <signum> 00301 * is invalid. 00302 */ 00303 virtual int remove_handler (int signum, 00304 ACE_Sig_Action *new_disp = 0, 00305 ACE_Sig_Action *old_disp = 0, 00306 int sigkey = -1); 00307 00308 // Set/get signal status. 00309 /// True if there is a pending signal. 00310 static int sig_pending (void); 00311 00312 /// Reset the value of <sig_pending_> so that no signal is pending. 00313 static void sig_pending (int); 00314 00315 // = Set/get the handler associated with a particular signal. 00316 00317 /// Return the ACE_Sig_Handler associated with <signum>. 00318 virtual ACE_Event_Handler *handler (int signum); 00319 00320 /// Set a new ACE_Event_Handler that is associated with <signum>. 00321 /// Return the existing handler. 00322 virtual ACE_Event_Handler *handler (int signum, 00323 ACE_Event_Handler *); 00324 00325 /** 00326 * Callback routine registered with sigaction(2) that dispatches the 00327 * <handle_signal> method of the appropriate pre-registered 00328 * ACE_Event_Handler. 00329 */ 00330 static void dispatch (int, siginfo_t *, 00331 ucontext_t *); 00332 00333 /// Dump the state of an object. 00334 void dump (void) const; 00335 00336 /// Declare the dynamic allocation hooks. 00337 ACE_ALLOC_HOOK_DECLARE; 00338 00339 protected: 00340 // = These methods and data members are shared by derived classes. 00341 00342 /** 00343 * Set a new ACE_Event_Handler that is associated with <signum>. 00344 * Return the existing handler. Does not acquire any locks so that 00345 * it can be called from a signal handler, such as <dispatch>. 00346 */ 00347 static ACE_Event_Handler *handler_i (int signum, 00348 ACE_Event_Handler *); 00349 00350 /** 00351 * This implementation method is called by <register_handler> and 00352 * <dispatch>. It doesn't do any locking so that it can be called 00353 * within a signal handler, such as <dispatch>. It adds a new 00354 * ACE_Event_Handler and a new sigaction associated with <signum>. 00355 * Passes back the existing ACE_Event_Handler and its sigaction if 00356 * pointers are non-zero. Returns -1 on failure and >= 0 on 00357 * success. 00358 */ 00359 static int register_handler_i (int signum, 00360 ACE_Event_Handler *new_sh, 00361 ACE_Sig_Action *new_disp = 0, 00362 ACE_Event_Handler **old_sh = 0, 00363 ACE_Sig_Action *old_disp = 0); 00364 00365 /// Check whether the SIGNUM is within the legal range of signals. 00366 static int in_range (int signum); 00367 00368 /// Keeps track of whether a signal is pending. 00369 static sig_atomic_t sig_pending_; 00370 00371 private: 00372 /// Array used to store one user-defined Event_Handler for every 00373 /// signal. 00374 static ACE_Event_Handler *signal_handlers_[ACE_NSIG]; 00375 }; 00376 00377 /** 00378 * @class ACE_Sig_Adapter 00379 * 00380 * @brief Provide an adapter that transforms various types of signal 00381 * handlers into the scheme used by the ACE_Reactor. 00382 */ 00383 class ACE_Export ACE_Sig_Adapter : public ACE_Event_Handler 00384 { 00385 public: 00386 ACE_Sig_Adapter (ACE_Sig_Action &, int sigkey); 00387 ACE_Sig_Adapter (ACE_Event_Handler *, int sigkey); 00388 ACE_Sig_Adapter (ACE_Sig_Handler_Ex, int sigkey = 0); 00389 ~ACE_Sig_Adapter (void); 00390 00391 /// Returns this signal key that's used to remove this from the 00392 /// ACE_Reactor's internal table. 00393 int sigkey (void); 00394 00395 /// Called by the <Reactor> to dispatch the signal handler. 00396 virtual int handle_signal (int, siginfo_t *, ucontext_t *); 00397 00398 private: 00399 /// Key for this signal handler (used to remove it). 00400 int sigkey_; 00401 00402 /// Is this an external handler or an ACE handler? 00403 enum 00404 { 00405 /// We're just wrapping an ACE_Event_Handler. 00406 ACE_HANDLER, 00407 /// An ACE_Sig_Action. 00408 SIG_ACTION, 00409 /// A normal C function. 00410 C_FUNCTION 00411 } type_; 00412 00413 // = This should be a union, but C++ won't allow that because the 00414 // <ACE_Sig_Action> has a constructor. 00415 /// This is an external handler (ugh). 00416 ACE_Sig_Action sa_; 00417 00418 /// This is an ACE hander. 00419 ACE_Event_Handler *eh_; 00420 00421 /// This is a normal C function. 00422 ACE_Sig_Handler_Ex sig_func_; 00423 }; 00424 00425 #if !defined (ACE_HAS_BROKEN_HPUX_TEMPLATES) 00426 /** 00427 * @class ACE_Sig_Handlers 00428 * 00429 * @brief This is an alternative signal handling dispatcher for ACE. It 00430 * allows a list of signal handlers to be registered for each 00431 * signal. It also makes SA_RESTART the default mode. 00432 * 00433 * Using this class a program can register one or more 00434 * ACE_Event_Handler with the ACE_Sig_Handler in order to 00435 * handle a designated <signum>. When a signal occurs that 00436 * corresponds to this <signum>, the <handle_signal> methods of 00437 * all the registered ACE_Event_Handlers are invoked 00438 * automatically. 00439 */ 00440 class ACE_Export ACE_Sig_Handlers : public ACE_Sig_Handler 00441 { 00442 public: 00443 // = Registration and removal methods. 00444 /** 00445 * Add a new ACE_Event_Handler and a new sigaction associated with 00446 * <signum>. Passes back the existing ACE_Event_Handler and its 00447 * sigaction if pointers are non-zero. Returns -1 on failure and 00448 * a <sigkey> that is >= 0 on success. 00449 */ 00450 virtual int register_handler (int signum, 00451 ACE_Event_Handler *new_sh, 00452 ACE_Sig_Action *new_disp = 0, 00453 ACE_Event_Handler **old_sh = 0, 00454 ACE_Sig_Action *old_disp = 0); 00455 00456 /** 00457 * Remove an ACE_Event_Handler currently associated with <signum>. 00458 * We remove the handler if (1) its <sigkey> matches the <sigkey> 00459 * passed as a parameter or (2) if we've been told to remove all the 00460 * handlers, i.e., <sigkey> == -1. If a new disposition is given it 00461 * is installed and the previous disposition is returned (if desired 00462 * by the caller). Returns 0 on success and -1 if <signum> is 00463 * invalid. 00464 */ 00465 virtual int remove_handler (int signum, 00466 ACE_Sig_Action *new_disp = 0, 00467 ACE_Sig_Action *old_disp = 0, 00468 int sigkey = -1); 00469 00470 // = Set/get the handler associated with a particular signal. 00471 00472 /// Return the head of the list of ACE_Sig_Handlers associated with 00473 /// SIGNUM. 00474 virtual ACE_Event_Handler *handler (int signum); 00475 00476 /** 00477 * Set a new ACE_Event_Handler that is associated with SIGNUM at 00478 * the head of the list of signals. Return the existing handler 00479 * that was at the head. 00480 */ 00481 virtual ACE_Event_Handler *handler (int signum, 00482 ACE_Event_Handler *); 00483 00484 /** 00485 * Callback routine registered with sigaction(2) that dispatches the 00486 * <handle_signal> method of all the pre-registered 00487 * ACE_Event_Handlers for <signum> 00488 */ 00489 static void dispatch (int signum, siginfo_t *, ucontext_t *); 00490 00491 /// Dump the state of an object. 00492 void dump (void) const; 00493 00494 /// Declare the dynamic allocation hooks. 00495 ACE_ALLOC_HOOK_DECLARE; 00496 00497 private: 00498 /** 00499 * Keeps track of the id that uniquely identifies each registered 00500 * signal handler. This id can be used to cancel a timer via the 00501 * <remove_handler> method. 00502 */ 00503 static int sigkey_; 00504 00505 /// If this is > 0 then a 3rd party library has registered a 00506 /// handler... 00507 static int third_party_sig_handler_; 00508 }; 00509 #endif /* ACE_HAS_BROKEN_HPUX_TEMPLATES */ 00510 00511 ACE_END_VERSIONED_NAMESPACE_DECL 00512 00513 #if defined (__ACE_INLINE__) 00514 #include "ace/Signal.inl" 00515 #endif /* __ACE_INLINE__ */ 00516 00517 #include /**/ "ace/post.h" 00518 #endif /* ACE_SIGNAL_HANDLER_H */