Chris Lattner | 24943d2 | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 1 | //===-- UnixSignals.cpp -----------------------------------------*- C++ -*-===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | |
| 10 | #include "lldb/Target/UnixSignals.h" |
| 11 | |
| 12 | // C Includes |
| 13 | // C++ Includes |
| 14 | // Other libraries and framework includes |
| 15 | // Project includes |
| 16 | |
| 17 | using namespace lldb_private; |
| 18 | |
| 19 | UnixSignals::Signal::Signal (const char *name, bool default_suppress, bool default_stop, bool default_notify) : |
| 20 | m_name (name), |
| 21 | m_conditions () |
| 22 | { |
| 23 | m_conditions[Signal::eCondSuppress] = default_suppress; |
| 24 | m_conditions[Signal::eCondStop] = default_stop; |
| 25 | m_conditions[Signal::eCondNotify] = default_notify; |
| 26 | } |
| 27 | |
| 28 | //---------------------------------------------------------------------- |
| 29 | // UnixSignals constructor |
| 30 | //---------------------------------------------------------------------- |
| 31 | UnixSignals::UnixSignals () |
| 32 | { |
| 33 | Reset (); |
| 34 | } |
| 35 | |
| 36 | //---------------------------------------------------------------------- |
| 37 | // Destructor |
| 38 | //---------------------------------------------------------------------- |
| 39 | UnixSignals::~UnixSignals () |
| 40 | { |
| 41 | } |
| 42 | |
| 43 | void |
| 44 | UnixSignals::Reset () |
| 45 | { |
| 46 | // This builds one standard set of Unix Signals. If yours aren't quite in this |
| 47 | // order, you can either subclass this class, and use Add & Remove to change them |
| 48 | // or you can subclass and build them afresh in your constructor; |
| 49 | m_signals.clear(); |
| 50 | |
| 51 | AddSignal(1, "SIGHUP", false, true, true ); // 1 hangup |
| 52 | AddSignal(2, "SIGINT", true, true, true ); // 2 interrupt |
| 53 | AddSignal(3, "SIGQUIT", false, true, true ); // 3 quit |
| 54 | AddSignal(4, "SIGILL", false, true, true ); // 4 illegal instruction (not reset when caught) |
| 55 | AddSignal(5, "SIGTRAP", true, true, true ); // 5 trace trap (not reset when caught) |
| 56 | AddSignal(6, "SIGABRT", false, true, true ); // 6 abort() |
| 57 | AddSignal(7, "SIGEMT", false, true, true ); // 7 pollable event ([XSR] generated, not supported) |
| 58 | AddSignal(8, "SIGFPE", false, true, true ); // 8 floating point exception |
| 59 | AddSignal(9, "SIGKILL", false, true, true ); // 9 kill (cannot be caught or ignored) |
| 60 | AddSignal(10, "SIGBUS", false, true, true ); // 10 bus error |
| 61 | AddSignal(11, "SIGSEGV", false, true, true ); // 11 segmentation violation |
| 62 | AddSignal(12, "SIGSYS", false, true, true ); // 12 bad argument to system call |
| 63 | AddSignal(13, "SIGPIPE", false, true, true ); // 13 write on a pipe with no one to read it |
| 64 | AddSignal(14, "SIGALRM", false, false, true ); // 14 alarm clock |
| 65 | AddSignal(15, "SIGTERM", false, true, true ); // 15 software termination signal from kill |
| 66 | AddSignal(16, "SIGURG", false, false, false); // 16 urgent condition on IO channel |
| 67 | AddSignal(17, "SIGSTOP", false, true, true ); // 17 sendable stop signal not from tty |
| 68 | AddSignal(18, "SIGTSTP", false, true, true ); // 18 stop signal from tty |
| 69 | AddSignal(19, "SIGCONT", false, true, true ); // 19 continue a stopped process |
| 70 | AddSignal(20, "SIGCHLD", false, false, true ); // 20 to parent on child stop or exit |
| 71 | AddSignal(21, "SIGTTIN", false, true, true ); // 21 to readers pgrp upon background tty read |
| 72 | AddSignal(22, "SIGTTOU", false, true, true ); // 22 like TTIN for output if (tp->t_local<OSTOP) |
| 73 | AddSignal(23, "SIGIO", false, false, false); // 23 input/output possible signal |
| 74 | AddSignal(24, "SIGXCPU", false, true, true ); // 24 exceeded CPU time limit |
| 75 | AddSignal(25, "SIGXFSZ", false, true, true ); // 25 exceeded file size limit |
| 76 | AddSignal(26, "SIGVTALRM", false, false, false); // 26 virtual time alarm |
| 77 | AddSignal(27, "SIGPROF", false, false, false); // 27 profiling time alarm |
| 78 | AddSignal(28, "SIGWINCH", false, false, false); // 28 window size changes |
| 79 | AddSignal(29, "SIGINFO", false, true, true ); // 29 information request |
| 80 | AddSignal(30, "SIGUSR1", false, true, true ); // 30 user defined signal 1 |
| 81 | AddSignal(31, "SIGUSR2", false, true, true ); // 31 user defined signal 2 |
| 82 | } |
| 83 | void |
| 84 | UnixSignals::AddSignal (int signo, const char *name, bool default_suppress, bool default_stop, bool default_notify) |
| 85 | { |
| 86 | collection::iterator iter = m_signals.find (signo); |
| 87 | struct Signal new_signal (name, default_suppress, default_stop, default_notify); |
| 88 | |
| 89 | if (iter != m_signals.end()) |
| 90 | m_signals.erase (iter); |
| 91 | |
| 92 | m_signals.insert (iter, collection::value_type (signo, new_signal)); |
| 93 | } |
| 94 | |
| 95 | void |
| 96 | UnixSignals::RemoveSignal (int signo) |
| 97 | { |
| 98 | collection::iterator pos = m_signals.find (signo); |
| 99 | if (pos != m_signals.end()) |
| 100 | m_signals.erase (pos); |
| 101 | } |
| 102 | |
| 103 | UnixSignals::Signal * |
| 104 | UnixSignals::GetSignalByName (const char *name, int32_t &signo) |
| 105 | { |
| 106 | ConstString const_name (name); |
| 107 | |
| 108 | collection::iterator pos, end = m_signals.end (); |
| 109 | for (pos = m_signals.begin (); pos != end; pos++) |
| 110 | { |
| 111 | if (const_name == (*pos).second.m_name) |
| 112 | { |
| 113 | signo = (*pos).first; |
| 114 | return &((*pos).second); |
| 115 | } |
| 116 | } |
| 117 | return NULL; |
| 118 | } |
| 119 | |
| 120 | |
| 121 | const UnixSignals::Signal * |
| 122 | UnixSignals::GetSignalByName (const char *name, int32_t &signo) const |
| 123 | { |
| 124 | ConstString const_name (name); |
| 125 | |
| 126 | collection::const_iterator pos, end = m_signals.end (); |
| 127 | for (pos = m_signals.begin (); pos != end; pos++) |
| 128 | { |
| 129 | if (const_name == (*pos).second.m_name) |
| 130 | { |
| 131 | signo = (*pos).first; |
| 132 | return &((*pos).second); |
| 133 | } |
| 134 | } |
| 135 | return NULL; |
| 136 | } |
| 137 | |
| 138 | const char * |
| 139 | UnixSignals::GetSignalAsCString (int signo) const |
| 140 | { |
| 141 | collection::const_iterator pos = m_signals.find (signo); |
| 142 | if (pos == m_signals.end()) |
| 143 | return NULL; |
| 144 | else |
| 145 | return (*pos).second.m_name.GetCString (); |
| 146 | } |
| 147 | |
| 148 | |
| 149 | bool |
| 150 | UnixSignals::SignalIsValid (int32_t signo) const |
| 151 | { |
| 152 | return m_signals.find (signo) != m_signals.end(); |
| 153 | } |
| 154 | |
| 155 | |
| 156 | int32_t |
| 157 | UnixSignals::GetSignalNumberFromName (const char *name) const |
| 158 | { |
| 159 | int32_t signo; |
| 160 | const Signal *signal = GetSignalByName (name, signo); |
| 161 | if (signal == NULL) |
| 162 | return LLDB_INVALID_SIGNAL_NUMBER; |
| 163 | else |
| 164 | return signo; |
| 165 | } |
| 166 | |
| 167 | int32_t |
| 168 | UnixSignals::GetFirstSignalNumber () const |
| 169 | { |
| 170 | if (m_signals.empty()) |
| 171 | return LLDB_INVALID_SIGNAL_NUMBER; |
| 172 | |
| 173 | return (*m_signals.begin ()).first; |
| 174 | } |
| 175 | |
| 176 | int32_t |
| 177 | UnixSignals::GetNextSignalNumber (int32_t current_signal) const |
| 178 | { |
| 179 | collection::const_iterator pos = m_signals.find (current_signal); |
| 180 | collection::const_iterator end = m_signals.end(); |
| 181 | if (pos == end) |
| 182 | return LLDB_INVALID_SIGNAL_NUMBER; |
| 183 | else |
| 184 | { |
| 185 | pos++; |
| 186 | if (pos == end) |
| 187 | return LLDB_INVALID_SIGNAL_NUMBER; |
| 188 | else |
| 189 | return (*pos).first; |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | const char * |
| 194 | UnixSignals::GetSignalInfo |
| 195 | ( |
| 196 | int32_t signo, |
| 197 | bool &should_suppress, |
| 198 | bool &should_stop, |
| 199 | bool &should_notify |
| 200 | ) const |
| 201 | { |
| 202 | collection::const_iterator pos = m_signals.find (signo); |
| 203 | if (pos == m_signals.end()) |
| 204 | return NULL; |
| 205 | else |
| 206 | { |
| 207 | const Signal &signal = (*pos).second; |
| 208 | should_suppress = signal.m_conditions[Signal::eCondSuppress]; |
| 209 | should_stop = signal.m_conditions[Signal::eCondStop]; |
| 210 | should_notify = signal.m_conditions[Signal::eCondNotify]; |
| 211 | return signal.m_name.AsCString(""); |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | bool |
| 216 | UnixSignals::GetCondition |
| 217 | ( |
| 218 | int32_t signo, |
| 219 | UnixSignals::Signal::Condition cond_pos |
| 220 | ) const |
| 221 | { |
| 222 | collection::const_iterator pos = m_signals.find (signo); |
| 223 | if (pos == m_signals.end()) |
| 224 | return false; |
| 225 | else |
| 226 | return (*pos).second.m_conditions[cond_pos]; |
| 227 | } |
| 228 | |
| 229 | bool |
| 230 | UnixSignals::SetCondition (int32_t signo, UnixSignals::Signal::Condition cond_pos, bool value) |
| 231 | { |
| 232 | collection::iterator pos = m_signals.find (signo); |
| 233 | if (pos == m_signals.end()) |
| 234 | return false; |
| 235 | else |
| 236 | { |
| 237 | bool ret_value = (*pos).second.m_conditions[cond_pos]; |
| 238 | (*pos).second.m_conditions[cond_pos] = value; |
| 239 | return ret_value; |
| 240 | } |
| 241 | } |
| 242 | |
| 243 | bool |
| 244 | UnixSignals::SetCondition (const char *signal_name, UnixSignals::Signal::Condition cond_pos, bool value) |
| 245 | { |
| 246 | int32_t signo; |
| 247 | Signal *signal = GetSignalByName (signal_name, signo); |
| 248 | if (signal == NULL) |
| 249 | return false; |
| 250 | else |
| 251 | { |
| 252 | bool ret_value = signal->m_conditions[cond_pos]; |
| 253 | signal->m_conditions[cond_pos] = value; |
| 254 | return ret_value; |
| 255 | } |
| 256 | } |
| 257 | |
| 258 | bool |
| 259 | UnixSignals::GetShouldSuppress (int signo) const |
| 260 | { |
| 261 | return GetCondition (signo, Signal::eCondSuppress); |
| 262 | } |
| 263 | |
| 264 | bool |
| 265 | UnixSignals::SetShouldSuppress (int signo, bool value) |
| 266 | { |
| 267 | return SetCondition (signo, Signal::eCondSuppress, value); |
| 268 | } |
| 269 | |
| 270 | bool |
| 271 | UnixSignals::SetShouldSuppress (const char *signal_name, bool value) |
| 272 | { |
| 273 | return SetCondition (signal_name, Signal::eCondSuppress, value); |
| 274 | } |
| 275 | |
| 276 | bool |
| 277 | UnixSignals::GetShouldStop (int signo) const |
| 278 | { |
| 279 | return GetCondition (signo, Signal::eCondStop); |
| 280 | } |
| 281 | |
| 282 | bool |
| 283 | UnixSignals::SetShouldStop (int signo, bool value) |
| 284 | { |
| 285 | return SetCondition (signo, Signal::eCondStop, value); |
| 286 | } |
| 287 | |
| 288 | bool |
| 289 | UnixSignals::SetShouldStop (const char *signal_name, bool value) |
| 290 | { |
| 291 | return SetCondition (signal_name, Signal::eCondStop, value); |
| 292 | } |
| 293 | |
| 294 | bool |
| 295 | UnixSignals::GetShouldNotify (int signo) const |
| 296 | { |
| 297 | return GetCondition (signo, Signal::eCondNotify); |
| 298 | } |
| 299 | |
| 300 | bool |
| 301 | UnixSignals::SetShouldNotify (int signo, bool value) |
| 302 | { |
| 303 | return SetCondition (signo, Signal::eCondNotify, value); |
| 304 | } |
| 305 | |
| 306 | bool |
| 307 | UnixSignals::SetShouldNotify (const char *signal_name, bool value) |
| 308 | { |
| 309 | return SetCondition (signal_name, Signal::eCondNotify, value); |
| 310 | } |