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