1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 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
SDL_Parachute(int sig)38 static void SDL_Parachute(int sig)
39 {
40 signal(sig, SIG_DFL);
41 SDL_Quit();
42 raise(sig);
43 }
44
45 static int SDL_fatal_signals[] = {
46 SIGSEGV,
47 #ifdef SIGBUS
48 SIGBUS,
49 #endif
50 #ifdef SIGFPE
51 SIGFPE,
52 #endif
53 #ifdef SIGQUIT
54 SIGQUIT,
55 #endif
56 0
57 };
58
SDL_InstallParachute(void)59 void SDL_InstallParachute(void)
60 {
61 /* Set a handler for any fatal signal not already handled */
62 int i;
63 #ifdef HAVE_SIGACTION
64 struct sigaction action;
65
66 for ( i=0; SDL_fatal_signals[i]; ++i ) {
67 sigaction(SDL_fatal_signals[i], NULL, &action);
68 if ( action.sa_handler == SIG_DFL ) {
69 action.sa_handler = SDL_Parachute;
70 sigaction(SDL_fatal_signals[i], &action, NULL);
71 }
72 }
73 #ifdef SIGALRM
74 /* Set SIGALRM to be ignored -- necessary on Solaris */
75 sigaction(SIGALRM, NULL, &action);
76 if ( action.sa_handler == SIG_DFL ) {
77 action.sa_handler = SIG_IGN;
78 sigaction(SIGALRM, &action, NULL);
79 }
80 #endif
81 #else
82 void (*ohandler)(int);
83
84 for ( i=0; SDL_fatal_signals[i]; ++i ) {
85 ohandler = signal(SDL_fatal_signals[i], SDL_Parachute);
86 if ( ohandler != SIG_DFL ) {
87 signal(SDL_fatal_signals[i], ohandler);
88 }
89 }
90 #endif /* HAVE_SIGACTION */
91 return;
92 }
93
SDL_UninstallParachute(void)94 void SDL_UninstallParachute(void)
95 {
96 /* Remove a handler for any fatal signal handled */
97 int i;
98 #ifdef HAVE_SIGACTION
99 struct sigaction action;
100
101 for ( i=0; SDL_fatal_signals[i]; ++i ) {
102 sigaction(SDL_fatal_signals[i], NULL, &action);
103 if ( action.sa_handler == SDL_Parachute ) {
104 action.sa_handler = SIG_DFL;
105 sigaction(SDL_fatal_signals[i], &action, NULL);
106 }
107 }
108 #else
109 void (*ohandler)(int);
110
111 for ( i=0; SDL_fatal_signals[i]; ++i ) {
112 ohandler = signal(SDL_fatal_signals[i], SIG_DFL);
113 if ( ohandler != SDL_Parachute ) {
114 signal(SDL_fatal_signals[i], ohandler);
115 }
116 }
117 #endif /* HAVE_SIGACTION */
118 }
119
120 #else
121
122 /* No signals on this platform, nothing to do.. */
123
SDL_InstallParachute(void)124 void SDL_InstallParachute(void)
125 {
126 return;
127 }
128
SDL_UninstallParachute(void)129 void SDL_UninstallParachute(void)
130 {
131 return;
132 }
133
134 #endif /* HAVE_SIGNAL_H */
135