blob: e6500c5dba837029410e62a275764961cf88fe76 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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
17using namespace lldb_private;
18
19UnixSignals::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//----------------------------------------------------------------------
31UnixSignals::UnixSignals ()
32{
33 Reset ();
34}
35
36//----------------------------------------------------------------------
37// Destructor
38//----------------------------------------------------------------------
39UnixSignals::~UnixSignals ()
40{
41}
42
43void
44UnixSignals::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&LTOSTOP)
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}
83void
84UnixSignals::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
95void
96UnixSignals::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
103UnixSignals::Signal *
104UnixSignals::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
121const UnixSignals::Signal *
122UnixSignals::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
138const char *
139UnixSignals::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
149bool
150UnixSignals::SignalIsValid (int32_t signo) const
151{
152 return m_signals.find (signo) != m_signals.end();
153}
154
155
156int32_t
157UnixSignals::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
167int32_t
168UnixSignals::GetFirstSignalNumber () const
169{
170 if (m_signals.empty())
171 return LLDB_INVALID_SIGNAL_NUMBER;
172
173 return (*m_signals.begin ()).first;
174}
175
176int32_t
177UnixSignals::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
193const char *
194UnixSignals::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
215bool
216UnixSignals::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
229bool
230UnixSignals::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
243bool
244UnixSignals::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
258bool
259UnixSignals::GetShouldSuppress (int signo) const
260{
261 return GetCondition (signo, Signal::eCondSuppress);
262}
263
264bool
265UnixSignals::SetShouldSuppress (int signo, bool value)
266{
267 return SetCondition (signo, Signal::eCondSuppress, value);
268}
269
270bool
271UnixSignals::SetShouldSuppress (const char *signal_name, bool value)
272{
273 return SetCondition (signal_name, Signal::eCondSuppress, value);
274}
275
276bool
277UnixSignals::GetShouldStop (int signo) const
278{
279 return GetCondition (signo, Signal::eCondStop);
280}
281
282bool
283UnixSignals::SetShouldStop (int signo, bool value)
284{
285 return SetCondition (signo, Signal::eCondStop, value);
286}
287
288bool
289UnixSignals::SetShouldStop (const char *signal_name, bool value)
290{
291 return SetCondition (signal_name, Signal::eCondStop, value);
292}
293
294bool
295UnixSignals::GetShouldNotify (int signo) const
296{
297 return GetCondition (signo, Signal::eCondNotify);
298}
299
300bool
301UnixSignals::SetShouldNotify (int signo, bool value)
302{
303 return SetCondition (signo, Signal::eCondNotify, value);
304}
305
306bool
307UnixSignals::SetShouldNotify (const char *signal_name, bool value)
308{
309 return SetCondition (signal_name, Signal::eCondNotify, value);
310}