HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_Signal.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT library (C++)
7  *
8  * COMMENTS: Wrapper on signal handlers.
9  * By instantiating an object of this type, the signal
10  * handler is set to the desired value. When this
11  * object is destructed, the signals are automatically
12  * returned to their previous values.
13  *
14  * NOTES: Since the constructor/destructor handle installing
15  * and removal of the signals, this can even be used
16  * within a block of code to allow signals to be caught
17  * temporarily.
18  * When installing signals permanently, it is suggested
19  * that signal(2) still be used. However, it is possible
20  * to use the static "override" method below.
21  */
22 
23 #ifndef __UT_Signal_h__
24 #define __UT_Signal_h__
25 
26 #include "UT_API.h"
27 #include <signal.h> // Get a list of signals for us please
28 
29 #if defined(GAMEOS)
30  #include "UT_GameOsUtil.h"
31 
32  #define SIGINT 2
33  #define SIGILL 4
34  #define SIGFPE 8
35  #define SIGSEGV 11
36  #define SIGTERM 15
37 
38  #define SIG_DFL ((__sighandler_t)0)
39  #define SIG_IGN ((__sighandler_t)1)
40  #define SIG_ERR ((__sighandler_t)1)
41 #endif
42 
43 #if defined(WIN32) || defined(GAMEOS)
44  // define all the signals not already defined by NT.
45  // Removed two signals that conflicted with defined NT signals.
46  // Reserved signal #'s on NT so far are: 2,4,8,11,15,21,22
47  // Please note that addSignal will silently ignore any non-handled
48  // windows handlers as the runtime library does parameter validation
49  // and rejects them.
50  #define SIGHUP 1
51  // WIN32: SIGINT 2
52  #define SIGQUIT 3
53  // WIN32: SIGILL 4
54  #define SIGTRAP 5 // Unhandled
55  #define SIGEMT 7 // Unhandled
56  // WIN32: SIGFPE 8
57  #define SIGKILL 9 // Unhandled
58  #define SIGBUS 10 // Unhandled
59  // WIN32: SIGSEGV 11
60  #define SIGSYS 12 // Unhandled
61  #define SIGPIPE 13
62  #define SIGALRM 14 // Unhandled
63  // WIN32: SIGTERM 15
64  #define SIGUSR1 16 // Windows: IOINT?
65  #define SIGUSR2 17 // Windows: STOP?
66  // do not use SIGCLD anymore! provided here for backwards
67  // compatibility only!
68  #define SIGCLD 18 // Unhandled
69  // SIGCCHLD is the new POSIX name for SIGCLD, use this instead
70  #define SIGCHLD 18 // Unhandled
71  #define SIGPWR 19 // Unhandled
72  #define SIGWINCH 20 // Unhandled
73  // WIN32: SIGBREAK 21
74  // It's probably ok that SIGURG (urgent socket condition) is handled the
75  // same as SIGBREAK since there's no such thing on NT
76  #define SIGURG 21
77  // WIN32: SIGABRT 22
78  #define SIGSTOP 23 // Unhandled
79  #define SIGTSTP 24 // Unhandled
80  #define SIGCONT 25 // Unhandled
81  #define SIGTTIN 26 // Unhandled
82  #define SIGTTOU 27 // Unhandled
83  #define SIGVTALRM 28 // Unhandled
84  #define SIGPROF 29 // Unhandled
85  #define SIGXCPU 30 // Unhandled
86  #define SIGXFSZ 31 // Unhandled
87  #define SIG32 32 // Unhandled
88  // According to Irix it supports all signal numbers between 0 and 64
89  // So all other signals should probably start at 65
90  #define SIGPOLL 65 // Unhandled
91 
92  #define sigset(a,b) signal(a,b)
93 #else
94 
95 #if !defined(SIGEMT)
96 #if defined(SIGUNUSED)
97 #define SIGEMT SIGUNUSED
98 #else
99 #define SIGEMT SIGBUS
100 #endif
101 #endif
102 
103 #if !defined(SIGSYS)
104 #if defined(SIGUNUSED)
105 #define SIGSYS SIGUNUSED
106 #else
107 #define SIGSYS SIGBUS
108 #endif
109 #endif
110 
111 #endif
112 
113 #define UT_MAX_SIGNALS 64 // Allow for POSIX standard
114 
115 #if defined(LINUX) || defined(MBSD)
116 #define SUPPORTS_SIGINFO
117 #endif
118 
120 {
121 public:
122  UTsignalHandlerArg(int signal_num)
123  : mySignalNum(signal_num),
124  myOpaqueCPUContext(0),
125  myDepthFromSignalHandler(0)
126  {}
127 
128  // Increment the depth from the signal handler in the copy constructor.
129  // That way, as the signal handler argument is passed from the signal
130  // handler function to other functions, we'll know how far back up
131  // in the stack the original signal handler function is.
133  : mySignalNum(sig_arg.mySignalNum),
134 #ifdef SUPPORTS_SIGINFO
135  mySignalInfo(sig_arg.mySignalInfo),
136 #endif
137  myOpaqueCPUContext(sig_arg.myOpaqueCPUContext),
138  myDepthFromSignalHandler(sig_arg.myDepthFromSignalHandler + 1)
139  {}
140 
141  int getSignalNum() const { return mySignalNum; }
142 
143 #ifdef SUPPORTS_SIGINFO
144  void setSignalInfo(siginfo_t *signal_info)
145  {
146  mySignalInfo = signal_info;
147  }
148  const siginfo_t *getSignalInfo() const { return mySignalInfo; }
149 #endif
150  void setSignalContext(void *opaque_cpu_context)
151  {
152  myOpaqueCPUContext = opaque_cpu_context;
153  }
154  const void *getOpaqueCPUContext() const { return myOpaqueCPUContext; }
155 
157  { return myDepthFromSignalHandler; }
158 
159 private:
160  int mySignalNum;
161  void *myOpaqueCPUContext;
162  int myDepthFromSignalHandler;
163 #ifdef SUPPORTS_SIGINFO
164  siginfo_t *mySignalInfo;
165 #endif
166 };
167 
168 
170 
171 
172 #if !defined(LINUX) && !defined(MBSD)
173 extern "C"
174 #endif
176 
178 {
179 public:
180  // Catch a specified signal. If signum <= 0, then all signals
181  // (except ABRT) are caught. There are two styles of constructors.
182  // One takes an old-style signal handler that is needed so we can easily
183  // specify SIG_DFL, SIG_IGN, and SIG_ERR as the signal behaviours. The
184  // other constructor takes our own data structure as an argument and is
185  // designed to support the SA_SIGINFO 3-argument style callback added in
186  // POSIX.1b.
187  // If ignore_prev is false, all other signal handlers for the raised
188  // signal will be called in the reverse order they were installed.
189  // Otherwise, only the last handler for this signal will be called.
190  explicit UT_Signal(int signum=0, UToldStyleSigHandler handler = SIG_DFL,
191  bool ignore_prev=false);
192  explicit UT_Signal(int signum, UTsigHandler handler,
193  bool ignore_prev=false);
194 
195  // Catch a specified set of signals. The first argument is an
196  // array of signal numbers to catch. The array should be
197  // null terminated (since there is no signal 0)
198  UT_Signal(const int signums[], UToldStyleSigHandler handler = SIG_DFL,
199  bool ignore_prev=false);
200  UT_Signal(const int signums[], UTsigHandler handler,
201  bool ignore_prev=false);
202 
203  // Destructing will restore the signals to their previous values.
204  ~UT_Signal();
205 
206  // The following method is made available to override the default
207  // handler without destructing the object. For example, in the
208  // signal handler, you may want to ignore further signals of a certain
209  // type. This method allows you to set the signals. In fact, it
210  // simply calls sigaction() with the new handler.
211  void override(int signum, UToldStyleSigHandler,
212  bool ignore_prev=false);
213  void override(int signum, UTsigHandler,
214  bool ignore_prev=false);
215 
216 private:
217  // This class keeps track of a signal handler callback that is either
218  // an old-style callback (one that accepts an int, like SIG_DFL or
219  // SIG_IGN) or a new-style callback (one that accepts a UTsignalHandlerArg).
220  class UT_API UT_ComboSignalHandler
221  {
222  public:
223  UT_ComboSignalHandler();
224  UT_ComboSignalHandler(UTsigHandler handler);
225  UT_ComboSignalHandler(UToldStyleSigHandler handler);
226 
227  UT_ComboSignalHandler &operator=(UTsigHandler handler);
228  UT_ComboSignalHandler &operator=(UToldStyleSigHandler handler);
229  bool operator!=(UToldStyleSigHandler handler) const;
230 
231  bool isSet() const;
232  void operator()(int signal_num,
233 #ifdef SUPPORTS_SIGINFO
234  siginfo_t *signal_info,
235 #endif
236  void *opaque_cpu_context) const;
237 
238  private:
239  union
240  {
241  UTsigHandler myNewStyle;
242  UToldStyleSigHandler myOldStyle;
243  } mySigHandler;
244  bool myIsOldStyleSigHandler;
245  };
246 
247  void constructPriv(int signum,
248  UT_ComboSignalHandler handler,
249  bool ignore_prev);
250  void constructPriv(const int signums[],
251  UT_ComboSignalHandler handler,
252  bool ignore_prev);
253  void addSignal(int signum, UT_ComboSignalHandler handler,
254  bool ignore_prev);
255  void removeSignal(int signum);
256  void updateActuals();
257  void overridePriv(int signum,
258  UT_ComboSignalHandler handler,
259  bool ignore_prev);
260 
261  static void processSignal(int signal_num
262 #ifdef SUPPORTS_SIGINFO
263  , siginfo_t *, void *
264 #endif
265  );
266 
267  UT_ComboSignalHandler mySignals[UT_MAX_SIGNALS];
268  bool myIgnorePrev[UT_MAX_SIGNALS];
269 
270  UT_Signal *myNext, *myPrev;
271 };
272 
273 #endif
int getSignalNum() const
Definition: UT_Signal.h:141
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
void(* UToldStyleSigHandler)(int)
Definition: UT_Signal.h:175
#define UT_API
Definition: UT_API.h:13
UTsignalHandlerArg(int signal_num)
Definition: UT_Signal.h:122
#define UT_MAX_SIGNALS
Definition: UT_Signal.h:113
typedef int
Definition: png.h:1175
void setSignalContext(void *opaque_cpu_context)
Definition: UT_Signal.h:150
UTsignalHandlerArg(const UTsignalHandlerArg &sig_arg)
Definition: UT_Signal.h:132
bool operator!=(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:165
void(* UTsigHandler)(UTsignalHandlerArg)
Definition: UT_Signal.h:169
const void * getOpaqueCPUContext() const
Definition: UT_Signal.h:154
int getDepthFromSignalHandler() const
Definition: UT_Signal.h:156