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 
28 #include "UT_Array.h"
29 
30 #include <signal.h> // Get a list of signals for us please
31 
32 #if defined(WIN32)
33  // define all the signals not already defined by NT.
34  // Removed two signals that conflicted with defined NT signals.
35  // Reserved signal #'s on NT so far are: 2,4,8,11,15,21,22
36  // Please note that addSignal will silently ignore any non-handled
37  // windows handlers as the runtime library does parameter validation
38  // and rejects them.
39  #define SIGHUP 1
40  // WIN32: SIGINT 2
41  #define SIGQUIT 3
42  // WIN32: SIGILL 4
43  #define SIGTRAP 5 // Unhandled
44  #define SIGEMT 7 // Unhandled
45  // WIN32: SIGFPE 8
46  #define SIGKILL 9 // Unhandled
47  #define SIGBUS 10 // Unhandled
48  // WIN32: SIGSEGV 11
49  #define SIGSYS 12 // Unhandled
50  #define SIGPIPE 13
51  #define SIGALRM 14 // Unhandled
52  // WIN32: SIGTERM 15
53  #define SIGUSR1 16 // Windows: IOINT?
54  #define SIGUSR2 17 // Windows: STOP?
55  // do not use SIGCLD anymore! provided here for backwards
56  // compatibility only!
57  #define SIGCLD 18 // Unhandled
58  // SIGCCHLD is the new POSIX name for SIGCLD, use this instead
59  #define SIGCHLD 18 // Unhandled
60  #define SIGPWR 19 // Unhandled
61  #define SIGWINCH 20 // Unhandled
62  // WIN32: SIGBREAK 21
63  // It's probably ok that SIGURG (urgent socket condition) is handled the
64  // same as SIGBREAK since there's no such thing on NT
65  #define SIGURG 21
66  // WIN32: SIGABRT 22
67  #define SIGSTOP 23 // Unhandled
68  #define SIGTSTP 24 // Unhandled
69  #define SIGCONT 25 // Unhandled
70  #define SIGTTIN 26 // Unhandled
71  #define SIGTTOU 27 // Unhandled
72  #define SIGVTALRM 28 // Unhandled
73  #define SIGPROF 29 // Unhandled
74  #define SIGXCPU 30 // Unhandled
75  #define SIGXFSZ 31 // Unhandled
76  #define SIG32 32 // Unhandled
77  // According to Irix it supports all signal numbers between 0 and 64
78  // So all other signals should probably start at 65
79  #define SIGPOLL 65 // Unhandled
80 
81  #define sigset(a,b) signal(a,b)
82 #else
83 
84 #if !defined(SIGEMT)
85 #if defined(SIGUNUSED)
86 #define SIGEMT SIGUNUSED
87 #else
88 #define SIGEMT SIGBUS
89 #endif
90 #endif
91 
92 #if !defined(SIGSYS)
93 #if defined(SIGUNUSED)
94 #define SIGSYS SIGUNUSED
95 #else
96 #define SIGSYS SIGBUS
97 #endif
98 #endif
99 
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 #if !defined(LINUX) && !defined(MBSD)
161 extern "C"
162 #endif
164 
166 {
167 public:
168  /// Catch a specified signal. If signum <= 0, then all signals
169  /// (except ABRT) are caught. There are two styles of constructors.
170  /// One takes an old-style signal handler that is needed so we can easily
171  /// specify SIG_DFL, SIG_IGN, and SIG_ERR as the signal behaviours. The
172  /// other constructor takes our own data structure as an argument and is
173  /// designed to support the SA_SIGINFO 3-argument style callback added in
174  /// POSIX.1b.
175  /// If ignore_prev is false, all other signal handlers for the raised
176  /// signal will be called in the reverse order they were installed.
177  /// Otherwise, only the last handler for this signal will be called.
178  explicit UT_Signal(int signum=0, UToldStyleSigHandler handler = SIG_DFL,
179  bool ignore_prev=false);
180  explicit UT_Signal(int signum, UTsigHandler handler,
181  bool ignore_prev=false);
182 
183  /// Catch a specified set of signals. The first argument is an
184  /// array of signal numbers to catch. The array should be
185  /// null terminated (since there is no signal 0)
186  template <std::size_t Size>
187  UT_Signal(const int (&signums)[Size], UToldStyleSigHandler handler = SIG_DFL,
188  bool ignore_prev=false)
189  {
190  constructPriv(signums, Size, handler, ignore_prev);
191  }
192  template <std::size_t Size>
193  UT_Signal(const int (&signums)[Size], UTsigHandler handler,
194  bool ignore_prev=false)
195  {
196  constructPriv(signums, Size, handler, ignore_prev);
197  }
198  explicit UT_Signal(const UT_Array<int> &signums, UTsigHandler handler,
199  bool ignore_prev = false);
200  explicit UT_Signal(const UT_Array<int> &signums,
201  UToldStyleSigHandler handler = SIG_DFL,
202  bool ignore_prev = false);
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  /// This disables the cant return behaviour used in UT_Signal. This
217  /// behaviour will abort the application on behalf of the application
218  /// itself for signals that it treats as cant return (i.e. SIGTERM). For
219  /// some applications the application needs to control the full shutdown
220  /// otherwise the application can end up erroring on exit.
221  static void disableCantReturn(bool disable);
222 
223 private:
224  /// This class keeps track of a signal handler callback that is either
225  /// an old-style callback (one that accepts an int, like SIG_DFL or
226  /// SIG_IGN) or a new-style callback (one that accepts a UTsignalHandlerArg).
227  class UT_API UT_ComboSignalHandler
228  {
229  public:
230  UT_ComboSignalHandler();
231  UT_ComboSignalHandler(UTsigHandler handler);
232  UT_ComboSignalHandler(UToldStyleSigHandler handler);
233 
234  UT_ComboSignalHandler &operator=(UTsigHandler handler);
235  UT_ComboSignalHandler &operator=(UToldStyleSigHandler handler);
236  bool operator!=(UToldStyleSigHandler handler) const;
237 
238  bool isSet() const;
239  void operator()(int signal_num,
240 #ifdef SUPPORTS_SIGINFO
241  siginfo_t *signal_info,
242 #endif
243  void *opaque_cpu_context) const;
244 
245  private:
246  union
247  {
248  UTsigHandler myNewStyle;
249  UToldStyleSigHandler myOldStyle;
250  } mySigHandler;
251  bool myIsOldStyleSigHandler;
252  };
253 
254  void constructPriv(int signum,
255  UT_ComboSignalHandler handler,
256  bool ignore_prev);
257  void constructPriv(const int signums[],
258  const std::size_t size,
259  UT_ComboSignalHandler handler,
260  bool ignore_prev);
261  void addSignal(int signum, UT_ComboSignalHandler handler,
262  bool ignore_prev);
263  void removeSignal(int signum);
264  void updateActuals();
265  void overridePriv(int signum,
266  UT_ComboSignalHandler handler,
267  bool ignore_prev);
268 
269  static void processSignal(int signal_num
270 #ifdef SUPPORTS_SIGINFO
271  , siginfo_t *, void *
272 #endif
273  );
274 
275  UT_ComboSignalHandler mySignals[UT_MAX_SIGNALS];
276  bool myIgnorePrev[UT_MAX_SIGNALS];
277 
278  UT_Signal *myNext, *myPrev;
279 };
280 
281 #endif
int getSignalNum() const
Definition: UT_Signal.h:130
void
Definition: png.h:1083
void(* UToldStyleSigHandler)(int)
Definition: UT_Signal.h:163
UT_Signal(const int(&signums)[Size], UToldStyleSigHandler handler=SIG_DFL, bool ignore_prev=false)
Definition: UT_Signal.h:187
#define UT_API
Definition: UT_API.h:14
UTsignalHandlerArg(int signal_num)
Definition: UT_Signal.h:111
GLsizeiptr size
Definition: glcorearb.h:663
#define UT_MAX_SIGNALS
Definition: UT_Signal.h:102
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
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
UT_Signal(const int(&signums)[Size], UTsigHandler handler, bool ignore_prev=false)
Definition: UT_Signal.h:193