HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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 #if !defined(SIGEMT) && defined(SIGUNUSED)
95 #define SIGEMT SIGUNUSED
96 #endif
97 #if !defined(SIGSYS) && defined(SIGUNUSED)
98 #define SIGSYS SIGUNUSED
99 #endif
100 #endif
101 
102 #define UT_MAX_SIGNALS 64 // Allow for POSIX standard
103 
104 #if defined(LINUX) || defined(MBSD)
105 #define SUPPORTS_SIGINFO
106 #endif
107 
109 {
110 public:
111  UTsignalHandlerArg(int signal_num)
112  : mySignalNum(signal_num),
113  myOpaqueCPUContext(0),
114  myDepthFromSignalHandler(0)
115  {}
116 
117  // Increment the depth from the signal handler in the copy constructor.
118  // That way, as the signal handler argument is passed from the signal
119  // handler function to other functions, we'll know how far back up
120  // in the stack the original signal handler function is.
122  : mySignalNum(sig_arg.mySignalNum),
123 #ifdef SUPPORTS_SIGINFO
124  mySignalInfo(sig_arg.mySignalInfo),
125 #endif
126  myOpaqueCPUContext(sig_arg.myOpaqueCPUContext),
127  myDepthFromSignalHandler(sig_arg.myDepthFromSignalHandler + 1)
128  {}
129 
130  int getSignalNum() const { return mySignalNum; }
131 
132 #ifdef SUPPORTS_SIGINFO
133  void setSignalInfo(siginfo_t *signal_info)
134  {
135  mySignalInfo = signal_info;
136  }
137  const siginfo_t *getSignalInfo() const { return mySignalInfo; }
138 #endif
139  void setSignalContext(void *opaque_cpu_context)
140  {
141  myOpaqueCPUContext = opaque_cpu_context;
142  }
143  const void *getOpaqueCPUContext() const { return myOpaqueCPUContext; }
144 
146  { return myDepthFromSignalHandler; }
147 
148 private:
149  int mySignalNum;
150  void *myOpaqueCPUContext;
151  int myDepthFromSignalHandler;
152 #ifdef SUPPORTS_SIGINFO
153  siginfo_t *mySignalInfo;
154 #endif
155 };
156 
157 
159 
160 
161 #if !defined(LINUX) && !defined(MBSD)
162 extern "C"
163 #endif
165 
167 {
168 public:
169  // Catch a specified signal. If signum <= 0, then all signals
170  // (except ABRT) are caught. There are two styles of constructors.
171  // One takes an old-style signal handler that is needed so we can easily
172  // specify SIG_DFL, SIG_IGN, and SIG_ERR as the signal behaviours. The
173  // other constructor takes our own data structure as an argument and is
174  // designed to support the SA_SIGINFO 3-argument style callback added in
175  // POSIX.1b.
176  // If ignore_prev is false, all other signal handlers for the raised
177  // signal will be called in the reverse order they were installed.
178  // Otherwise, only the last handler for this signal will be called.
179  explicit UT_Signal(int signum=0, UToldStyleSigHandler handler = SIG_DFL,
180  bool ignore_prev=false);
181  explicit UT_Signal(int signum, UTsigHandler handler,
182  bool ignore_prev=false);
183 
184  // Catch a specified set of signals. The first argument is an
185  // array of signal numbers to catch. The array should be
186  // null terminated (since there is no signal 0)
187  UT_Signal(const int signums[], UToldStyleSigHandler handler = SIG_DFL,
188  bool ignore_prev=false);
189  UT_Signal(const int signums[], UTsigHandler handler,
190  bool ignore_prev=false);
191 
192  // Destructing will restore the signals to their previous values.
193  ~UT_Signal();
194 
195  // The following method is made available to override the default
196  // handler without destructing the object. For example, in the
197  // signal handler, you may want to ignore further signals of a certain
198  // type. This method allows you to set the signals. In fact, it
199  // simply calls sigaction() with the new handler.
200  void override(int signum, UToldStyleSigHandler,
201  bool ignore_prev=false);
202  void override(int signum, UTsigHandler,
203  bool ignore_prev=false);
204 
205 private:
206  // This class keeps track of a signal handler callback that is either
207  // an old-style callback (one that accepts an int, like SIG_DFL or
208  // SIG_IGN) or a new-style callback (one that accepts a UTsignalHandlerArg).
209  class UT_API UT_ComboSignalHandler
210  {
211  public:
212  UT_ComboSignalHandler();
213  UT_ComboSignalHandler(UTsigHandler handler);
214  UT_ComboSignalHandler(UToldStyleSigHandler handler);
215 
216  UT_ComboSignalHandler &operator=(UTsigHandler handler);
217  UT_ComboSignalHandler &operator=(UToldStyleSigHandler handler);
218  bool operator!=(UToldStyleSigHandler handler) const;
219 
220  bool isSet() const;
221  void operator()(int signal_num,
222 #ifdef SUPPORTS_SIGINFO
223  siginfo_t *signal_info,
224 #endif
225  void *opaque_cpu_context) const;
226 
227  private:
228  union
229  {
230  UTsigHandler myNewStyle;
231  UToldStyleSigHandler myOldStyle;
232  } mySigHandler;
233  bool myIsOldStyleSigHandler;
234  };
235 
236  void constructPriv(int signum,
237  UT_ComboSignalHandler handler,
238  bool ignore_prev);
239  void constructPriv(const int signums[],
240  UT_ComboSignalHandler handler,
241  bool ignore_prev);
242  void addSignal(int signum, UT_ComboSignalHandler handler,
243  bool ignore_prev);
244  void removeSignal(int signum);
245  void updateActuals();
246  void overridePriv(int signum,
247  UT_ComboSignalHandler handler,
248  bool ignore_prev);
249 
250  static void processSignal(int signal_num
251 #ifdef SUPPORTS_SIGINFO
252  , siginfo_t *, void *
253 #endif
254  );
255 
256  UT_ComboSignalHandler mySignals[UT_MAX_SIGNALS];
257  bool myIgnorePrev[UT_MAX_SIGNALS];
258 
259  UT_Signal *myNext, *myPrev;
260 };
261 
262 #endif
int getSignalNum() const
Definition: UT_Signal.h:130
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
void(* UToldStyleSigHandler)(int)
Definition: UT_Signal.h:164
#define UT_API
Definition: UT_API.h:12
UTsignalHandlerArg(int signal_num)
Definition: UT_Signal.h:111
#define UT_MAX_SIGNALS
Definition: UT_Signal.h:102
typedef int
Definition: png.h:1175
void setSignalContext(void *opaque_cpu_context)
Definition: UT_Signal.h:139
UTsignalHandlerArg(const UTsignalHandlerArg &sig_arg)
Definition: UT_Signal.h:121
bool operator!=(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:165
void(* UTsigHandler)(UTsignalHandlerArg)
Definition: UT_Signal.h:158
const void * getOpaqueCPUContext() const
Definition: UT_Signal.h:143
int getDepthFromSignalHandler() const
Definition: UT_Signal.h:145