1 |
/* |
2 |
SDL - Simple DirectMedia Layer |
3 |
Copyright (C) 1997-2011 Sam Lantinga |
4 |
|
5 |
This library is free software; you can redistribute it and/or |
6 |
modify it under the terms of the GNU Lesser General Public |
7 |
License as published by the Free Software Foundation; either |
8 |
version 2.1 of the License, or (at your option) any later version. |
9 |
|
10 |
This library is distributed in the hope that it will be useful, |
11 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 |
Lesser General Public License for more details. |
14 |
|
15 |
You should have received a copy of the GNU Lesser General Public |
16 |
License along with this library; if not, write to the Free Software |
17 |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
18 |
|
19 |
Sam Lantinga |
20 |
slouken@libsdl.org |
21 |
*/ |
22 |
#include "SDL_config.h" |
23 |
|
24 |
/* General fatal signal handling code for SDL */ |
25 |
|
26 |
#ifdef HAVE_SIGNAL_H |
27 |
|
28 |
#include <signal.h> |
29 |
|
30 |
#include "SDL.h" |
31 |
#include "SDL_fatal.h" |
32 |
|
33 |
/* This installs some signal handlers for the more common fatal signals, |
34 |
so that if the programmer is lazy, the app doesn't die so horribly if |
35 |
the program crashes. |
36 |
*/ |
37 |
|
38 |
static void |
39 |
SDL_Parachute(int sig) |
40 |
{ |
41 |
signal(sig, SIG_DFL); |
42 |
SDL_Quit(); |
43 |
raise(sig); |
44 |
} |
45 |
|
46 |
static const int SDL_fatal_signals[] = { |
47 |
SIGSEGV, |
48 |
#ifdef SIGBUS |
49 |
SIGBUS, |
50 |
#endif |
51 |
#ifdef SIGFPE |
52 |
SIGFPE, |
53 |
#endif |
54 |
#ifdef SIGQUIT |
55 |
SIGQUIT, |
56 |
#endif |
57 |
0 |
58 |
}; |
59 |
|
60 |
void |
61 |
SDL_InstallParachute(void) |
62 |
{ |
63 |
/* Set a handler for any fatal signal not already handled */ |
64 |
int i; |
65 |
#ifdef HAVE_SIGACTION |
66 |
struct sigaction action; |
67 |
|
68 |
for (i = 0; SDL_fatal_signals[i]; ++i) { |
69 |
sigaction(SDL_fatal_signals[i], NULL, &action); |
70 |
if (action.sa_handler == SIG_DFL) { |
71 |
action.sa_handler = SDL_Parachute; |
72 |
sigaction(SDL_fatal_signals[i], &action, NULL); |
73 |
} |
74 |
} |
75 |
#ifdef SIGALRM |
76 |
/* Set SIGALRM to be ignored -- necessary on Solaris */ |
77 |
sigaction(SIGALRM, NULL, &action); |
78 |
if (action.sa_handler == SIG_DFL) { |
79 |
action.sa_handler = SIG_IGN; |
80 |
sigaction(SIGALRM, &action, NULL); |
81 |
} |
82 |
#endif |
83 |
#else |
84 |
void (*ohandler) (int); |
85 |
|
86 |
for (i = 0; SDL_fatal_signals[i]; ++i) { |
87 |
ohandler = signal(SDL_fatal_signals[i], SDL_Parachute); |
88 |
if (ohandler != SIG_DFL) { |
89 |
signal(SDL_fatal_signals[i], ohandler); |
90 |
} |
91 |
} |
92 |
#endif /* HAVE_SIGACTION */ |
93 |
return; |
94 |
} |
95 |
|
96 |
void |
97 |
SDL_UninstallParachute(void) |
98 |
{ |
99 |
/* Remove a handler for any fatal signal handled */ |
100 |
int i; |
101 |
#ifdef HAVE_SIGACTION |
102 |
struct sigaction action; |
103 |
|
104 |
for (i = 0; SDL_fatal_signals[i]; ++i) { |
105 |
sigaction(SDL_fatal_signals[i], NULL, &action); |
106 |
if (action.sa_handler == SDL_Parachute) { |
107 |
action.sa_handler = SIG_DFL; |
108 |
sigaction(SDL_fatal_signals[i], &action, NULL); |
109 |
} |
110 |
} |
111 |
#else |
112 |
void (*ohandler) (int); |
113 |
|
114 |
for (i = 0; SDL_fatal_signals[i]; ++i) { |
115 |
ohandler = signal(SDL_fatal_signals[i], SIG_DFL); |
116 |
if (ohandler != SDL_Parachute) { |
117 |
signal(SDL_fatal_signals[i], ohandler); |
118 |
} |
119 |
} |
120 |
#endif /* HAVE_SIGACTION */ |
121 |
} |
122 |
|
123 |
#else |
124 |
|
125 |
/* No signals on this platform, nothing to do.. */ |
126 |
|
127 |
void |
128 |
SDL_InstallParachute(void) |
129 |
{ |
130 |
return; |
131 |
} |
132 |
|
133 |
void |
134 |
SDL_UninstallParachute(void) |
135 |
{ |
136 |
return; |
137 |
} |
138 |
|
139 |
#endif /* HAVE_SIGNAL_H */ |
140 |
/* vi: set ts=4 sw=4 expandtab: */ |