00001 /* 00002 * Copyright (C) 2003-2009 Olivier Boudeville 00003 * 00004 * This file is part of the Ceylan library. 00005 * 00006 * The Ceylan library is free software: you can redistribute it and/or modify 00007 * it under the terms of either the GNU Lesser General Public License or 00008 * the GNU General Public License, as they are published by the Free Software 00009 * Foundation, either version 3 of these Licenses, or (at your option) 00010 * any later version. 00011 * 00012 * The Ceylan library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License and the GNU General Public License 00016 * for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License and the GNU General Public License along with the Ceylan library. 00020 * If not, see <http://www.gnu.org/licenses/>. 00021 * 00022 * Author: Olivier Boudeville (olivier.boudeville@esperide.com) 00023 * 00024 */ 00025 00026 00027 #include "CeylanSignal.h" 00028 00029 00030 #ifdef CEYLAN_USES_CONFIG_H 00031 #include "CeylanConfig.h" // for configure-time feature settings 00032 #endif // CEYLAN_USES_CONFIG_H 00033 00034 00035 extern "C" 00036 { 00037 00038 #ifdef CEYLAN_USES_SIGNAL_H 00039 #include <signal.h> // for SIGHUP, etc. 00040 #endif // CEYLAN_USES_SIGNAL_H 00041 00042 } 00043 00044 00045 00046 /* 00047 * Maybe later: 00048 * - use sigaction instead of signal 00049 * - support the signals not in the POSIX.1 standard but described in SUSv2 00050 * and SUSv3 / POSIX 1003.1-2001, including real-time signals. 00051 * 00052 */ 00053 00054 #ifdef CEYLAN_USES_SIGNAL_H 00055 00056 00057 const Ceylan::System::Signal::SignalHandler 00058 Ceylan::System::Signal::IgnoringHandler = SIG_IGN ; 00059 00060 const Ceylan::System::Signal::SignalHandler 00061 Ceylan::System::Signal::DefaultHandler = SIG_DFL ; 00062 00063 00064 #else // CEYLAN_USES_SIGNAL_H 00065 00066 00067 const Ceylan::System::Signal::SignalHandler 00068 Ceylan::System::Signal::IgnoringHandler = 0 ; 00069 00070 const Ceylan::System::Signal::SignalHandler 00071 Ceylan::System::Signal::DefaultHandler = 0 ; 00072 00073 00074 #endif // CEYLAN_USES_SIGNAL_H 00075 00076 00077 00079 typedef Ceylan::System::Signal::SignalNumber Sig ; 00080 00081 00082 00083 #ifdef CEYLAN_USES_SIGNAL_H 00084 00085 /* 00086 * These constants are the ones for i386, ppc and sh. 00087 * For alpha and sparc, and for mips, there are other values. 00088 * 00089 */ 00090 00091 00092 /* 00093 * The first set of signal constants is known from both the UNIX 00094 * and the Windows world. 00095 * 00096 */ 00097 00098 const Sig Ceylan::System::Signal::InterruptFromKeyboard = SIGINT ; 00099 const Sig Ceylan::System::Signal::IllegalInstruction = SIGILL ; 00100 const Sig Ceylan::System::Signal::Abort = SIGABRT ; 00101 const Sig Ceylan::System::Signal::FloatingPointException = SIGFPE ; 00102 const Sig Ceylan::System::Signal::InvalidMemoryReference = SIGSEGV ; 00103 const Sig Ceylan::System::Signal::Termination = SIGTERM ; 00104 00105 00106 /* 00107 * The second set of signal constants is known from the UNIX 00108 * world only (not defined on Windows). 00109 * 00110 */ 00111 00112 #if CEYLAN_ARCH_WINDOWS 00113 00114 // Fake values since symbols have to be defined: 00115 00116 const Sig Ceylan::System::Signal::HangUp = 1 ; 00117 const Sig Ceylan::System::Signal::QuitFromKeyboard = 3 ; 00118 const Sig Ceylan::System::Signal::Kill = 7 ; 00119 const Sig Ceylan::System::Signal::BrokenPipe = 9 ; 00120 const Sig Ceylan::System::Signal::TimerSignal = 10 ; 00121 const Sig Ceylan::System::Signal::FirstUserDefined = 12 ; 00122 const Sig Ceylan::System::Signal::SecondUserDefined = 13 ; 00123 const Sig Ceylan::System::Signal::ChildEnded = 14 ; 00124 const Sig Ceylan::System::Signal::Continue = 15 ; 00125 const Sig Ceylan::System::Signal::Stop = 16 ; 00126 const Sig Ceylan::System::Signal::TtyStopped = 17 ; 00127 const Sig Ceylan::System::Signal::TtyInput = 18 ; 00128 const Sig Ceylan::System::Signal::TtyOutput = 19 ; 00129 00130 #else // CEYLAN_ARCH_WINDOWS 00131 00132 const Sig Ceylan::System::Signal::HangUp = SIGHUP ; 00133 const Sig Ceylan::System::Signal::QuitFromKeyboard = SIGQUIT ; 00134 const Sig Ceylan::System::Signal::Kill = SIGKILL ; 00135 const Sig Ceylan::System::Signal::BrokenPipe = SIGPIPE ; 00136 const Sig Ceylan::System::Signal::TimerSignal = SIGALRM ; 00137 const Sig Ceylan::System::Signal::FirstUserDefined = SIGUSR1 ; 00138 const Sig Ceylan::System::Signal::SecondUserDefined = SIGUSR2 ; 00139 const Sig Ceylan::System::Signal::ChildEnded = SIGCHLD ; 00140 const Sig Ceylan::System::Signal::Continue = SIGCONT ; 00141 const Sig Ceylan::System::Signal::Stop = SIGSTOP ; 00142 const Sig Ceylan::System::Signal::TtyStopped = SIGTSTP ; 00143 const Sig Ceylan::System::Signal::TtyInput = SIGTTIN ; 00144 const Sig Ceylan::System::Signal::TtyOutput = SIGTTOU ; 00145 00146 #endif // CEYLAN_ARCH_WINDOWS 00147 00148 #else // CEYLAN_USES_SIGNAL_H 00149 00150 00151 // Fake values since symbols have to be defined: 00152 00153 const Sig Ceylan::System::Signal::HangUp = 1 ; 00154 const Sig Ceylan::System::Signal::InterruptFromKeyboard = 2 ; 00155 const Sig Ceylan::System::Signal::QuitFromKeyboard = 3 ; 00156 const Sig Ceylan::System::Signal::IllegalInstruction = 4 ; 00157 const Sig Ceylan::System::Signal::Abort = 5 ; 00158 const Sig Ceylan::System::Signal::FloatingPointException = 6 ; 00159 const Sig Ceylan::System::Signal::Kill = 7 ; 00160 const Sig Ceylan::System::Signal::InvalidMemoryReference = 8 ; 00161 const Sig Ceylan::System::Signal::BrokenPipe = 9 ; 00162 const Sig Ceylan::System::Signal::TimerSignal = 10 ; 00163 const Sig Ceylan::System::Signal::Termination = 11 ; 00164 const Sig Ceylan::System::Signal::FirstUserDefined = 12 ; 00165 const Sig Ceylan::System::Signal::SecondUserDefined = 13 ; 00166 const Sig Ceylan::System::Signal::ChildEnded = 14 ; 00167 const Sig Ceylan::System::Signal::Continue = 15 ; 00168 const Sig Ceylan::System::Signal::Stop = 16 ; 00169 const Sig Ceylan::System::Signal::TtyStopped = 17 ; 00170 const Sig Ceylan::System::Signal::TtyInput = 18 ; 00171 const Sig Ceylan::System::Signal::TtyOutput = 19 ; 00172 00173 00174 #endif // CEYLAN_USES_SIGNAL_H 00175 00176 00177 00178 using namespace Ceylan::System::Signal ; 00179 00180 using std::string ; 00181 00182 00183 00184 SignalException::SignalException( const string & reason ) : 00185 SystemException( reason ) 00186 { 00187 00188 } 00189 00190 00191 00192 SignalException::~SignalException() throw() 00193 { 00194 00195 } 00196 00197 00198 00199 00200 00201 void Ceylan::System::Signal::setHandler( SignalNumber signalNumber, 00202 SignalHandler newHandler ) 00203 { 00204 00205 #if CEYLAN_USES_SIGNALS 00206 00207 if ( ::signal( 00208 static_cast<int>( signalNumber ), newHandler ) == SIG_ERR ) 00209 throw SignalException( "Signal::setHandler failed for signal " 00210 + Signal::toString( signalNumber ) ) ; 00211 00212 #else // CEYLAN_USES_SIGNALS 00213 00214 throw SignalException( "Signal::setHandler: " 00215 "signal feature not available." ) ; 00216 00217 #endif // CEYLAN_USES_SIGNALS 00218 00219 } 00220 00221 00222 00223 void Ceylan::System::Signal::setToDefaultHandler( SignalNumber signalNumber ) 00224 { 00225 00226 setHandler( signalNumber, DefaultHandler ) ; 00227 00228 } 00229 00230 00231 00232 void Ceylan::System::Signal::ignore( SignalNumber signalNumber ) 00233 { 00234 00235 setHandler( signalNumber, IgnoringHandler ) ; 00236 00237 } 00238 00239 00240 00241 void Ceylan::System::Signal::raise( SignalNumber signalNumber ) 00242 { 00243 00244 #if CEYLAN_USES_SIGNALS 00245 00246 ::raise( static_cast<int>( signalNumber ) ) ; 00247 00248 #else // CEYLAN_USES_SIGNALS 00249 00250 throw SignalException( "Signal::raise: signal feature not available." ) ; 00251 00252 #endif // CEYLAN_USES_SIGNALS 00253 00254 } 00255 00256 00257 00258 const std::string Ceylan::System::Signal::toString( SignalNumber signalNumber ) 00259 { 00260 00261 #if CEYLAN_USES_SIGNALS 00262 00263 00264 if ( signalNumber == Ceylan::System::Signal::HangUp ) 00265 return "Hangup detected on controlling terminal " 00266 "or death of controlling process (SIGHUP)" ; 00267 00268 if ( signalNumber == Ceylan::System::Signal::InterruptFromKeyboard ) 00269 return "Interrupt from keyboard (SIGINT)" ; 00270 00271 if ( signalNumber == Ceylan::System::Signal::QuitFromKeyboard ) 00272 return "Quit from keyboard (SIGQUIT)" ; 00273 00274 if ( signalNumber == Ceylan::System::Signal::IllegalInstruction ) 00275 return "Illegal Instruction (SIGILL)" ; 00276 00277 if ( signalNumber == Ceylan::System::Signal::Abort ) 00278 return "Abort signal from abort (SIGABRT)" ; 00279 00280 if ( signalNumber == Ceylan::System::Signal::FloatingPointException ) 00281 return "Floating point exception (SIGFPE)" ; 00282 00283 if ( signalNumber == Ceylan::System::Signal::Kill ) 00284 return "Kill signal (SIGKILL)" ; 00285 00286 if ( signalNumber == Ceylan::System::Signal::InvalidMemoryReference ) 00287 return "Invalid memory reference (SIGSEGV)" ; 00288 00289 if ( signalNumber == Ceylan::System::Signal::BrokenPipe ) 00290 return "Broken pipe: write to pipe with no readers (SIGPIPE)" ; 00291 00292 if ( signalNumber == Ceylan::System::Signal::TimerSignal ) 00293 return "Timer signal from alarm (SIGALRM)" ; 00294 00295 if ( signalNumber == Ceylan::System::Signal::Termination ) 00296 return "Termination signal (SIGTERM)" ; 00297 00298 if ( signalNumber == Ceylan::System::Signal::FirstUserDefined ) 00299 return "First user-defined signal (SIGUSR1)" ; 00300 00301 if ( signalNumber == Ceylan::System::Signal::SecondUserDefined ) 00302 return "Second user-defined signal (SIGUSR2)" ; 00303 00304 if ( signalNumber == Ceylan::System::Signal::ChildEnded ) 00305 return "Child stopped or terminated (SIGCHLD)" ; 00306 00307 if ( signalNumber == Ceylan::System::Signal::Continue ) 00308 return "Continue if stopped (SIGCONT)" ; 00309 00310 if ( signalNumber == Ceylan::System::Signal::Stop ) 00311 return "Stop process (SIGSTOP)" ; 00312 00313 if ( signalNumber == Ceylan::System::Signal::TtyStopped ) 00314 return "Stop typed at tty (SIGTSTP)" ; 00315 00316 if ( signalNumber == Ceylan::System::Signal::TtyInput ) 00317 return "tty input for background process (SIGTTIN)" ; 00318 00319 if ( signalNumber == Ceylan::System::Signal::TtyOutput ) 00320 return "tty output for background process (SIGTTOU)" ; 00321 00322 return "unknown signal (abnormal)" ; 00323 00324 00325 #else // CEYLAN_USES_SIGNALS 00326 00327 return "Signal::toString: signal feature not available." ; 00328 00329 #endif // CEYLAN_USES_SIGNALS 00330 00331 } 00332