src/SDL_fatal.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 01 Feb 2006 06:32:25 +0000
changeset 1312 c9b51268668f
parent 1152 51a8702d8ecd
child 1330 450721ad5436
permissions -rw-r--r--
Updated copyright information and removed rcs id lines (problematic in branch merges)
I batch edited these files, so please let me know if I've accidentally removed anybody's
credit here.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2006 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 
    23 #ifdef _WIN32_WCE
    24 #define NO_SIGNAL_H
    25 #endif
    26  
    27 /* General fatal signal handling code for SDL */
    28 
    29 #ifdef NO_SIGNAL_H
    30 
    31 /* No signals on this platform, nothing to do.. */
    32 
    33 void SDL_InstallParachute(void)
    34 {
    35 	return;
    36 }
    37 
    38 void SDL_UninstallParachute(void)
    39 {
    40 	return;
    41 }
    42 
    43 #else
    44 
    45 #include <stdlib.h>
    46 #include <stdio.h>
    47 #include <signal.h>
    48 #include <string.h>
    49 
    50 #include "SDL.h"
    51 #include "SDL_fatal.h"
    52 
    53 #ifdef __CYGWIN__
    54 #define DISABLE_STDIO
    55 #endif
    56 
    57 /* This installs some signal handlers for the more common fatal signals,
    58    so that if the programmer is lazy, the app doesn't die so horribly if
    59    the program crashes.
    60 */
    61 
    62 static void print_msg(const char *text)
    63 {
    64 #ifndef DISABLE_STDIO
    65 	fprintf(stderr, "%s", text);
    66 #endif
    67 }
    68 
    69 static void SDL_Parachute(int sig)
    70 {
    71 	signal(sig, SIG_DFL);
    72 	print_msg("Fatal signal: ");
    73 	switch (sig) {
    74 		case SIGSEGV:
    75 			print_msg("Segmentation Fault");
    76 			break;
    77 #ifdef SIGBUS
    78 #if SIGBUS != SIGSEGV
    79 		case SIGBUS:
    80 			print_msg("Bus Error");
    81 			break;
    82 #endif
    83 #endif /* SIGBUS */
    84 #ifdef SIGFPE
    85 		case SIGFPE:
    86 			print_msg("Floating Point Exception");
    87 			break;
    88 #endif /* SIGFPE */
    89 #ifdef SIGQUIT
    90 		case SIGQUIT:
    91 			print_msg("Keyboard Quit");
    92 			break;
    93 #endif /* SIGQUIT */
    94 #ifdef SIGPIPE
    95 		case SIGPIPE:
    96 			print_msg("Broken Pipe");
    97 			break;
    98 #endif /* SIGPIPE */
    99 		default:
   100 #ifndef DISABLE_STDIO
   101 			fprintf(stderr, "# %d", sig);
   102 #endif
   103 			break;
   104 	}
   105 	print_msg(" (SDL Parachute Deployed)\n");
   106 	SDL_Quit();
   107 	exit(-sig);
   108 }
   109 
   110 static int SDL_fatal_signals[] = {
   111 	SIGSEGV,
   112 #ifdef SIGBUS
   113 	SIGBUS,
   114 #endif
   115 #ifdef SIGFPE
   116 	SIGFPE,
   117 #endif
   118 #ifdef SIGQUIT
   119 	SIGQUIT,
   120 #endif
   121 	0
   122 };
   123 
   124 void SDL_InstallParachute(void)
   125 {
   126 	/* Set a handler for any fatal signal not already handled */
   127 	int i;
   128 #ifdef HAVE_SIGACTION
   129 	struct sigaction action;
   130 
   131 	for ( i=0; SDL_fatal_signals[i]; ++i ) {
   132 		sigaction(SDL_fatal_signals[i], NULL, &action);
   133 		if ( action.sa_handler == SIG_DFL ) {
   134 			action.sa_handler = SDL_Parachute;
   135 			sigaction(SDL_fatal_signals[i], &action, NULL);
   136 		}
   137 	}
   138 #ifdef SIGALRM
   139 	/* Set SIGALRM to be ignored -- necessary on Solaris */
   140 	sigaction(SIGALRM, NULL, &action);
   141 	if ( action.sa_handler == SIG_DFL ) {
   142 		action.sa_handler = SIG_IGN;
   143 		sigaction(SIGALRM, &action, NULL);
   144 	}
   145 #endif
   146 #else
   147 	void (*ohandler)(int);
   148 
   149 	for ( i=0; SDL_fatal_signals[i]; ++i ) {
   150 		ohandler = signal(SDL_fatal_signals[i], SDL_Parachute);
   151 		if ( ohandler != SIG_DFL ) {
   152 			signal(SDL_fatal_signals[i], ohandler);
   153 		}
   154 	}
   155 #endif /* HAVE_SIGACTION */
   156 	return;
   157 }
   158 
   159 void SDL_UninstallParachute(void)
   160 {
   161 	/* Remove a handler for any fatal signal handled */
   162 	int i;
   163 #ifdef HAVE_SIGACTION
   164 	struct sigaction action;
   165 
   166 	for ( i=0; SDL_fatal_signals[i]; ++i ) {
   167 		sigaction(SDL_fatal_signals[i], NULL, &action);
   168 		if ( action.sa_handler == SDL_Parachute ) {
   169 			action.sa_handler = SIG_DFL;
   170 			sigaction(SDL_fatal_signals[i], &action, NULL);
   171 		}
   172 	}
   173 #else
   174 	void (*ohandler)(int);
   175 
   176 	for ( i=0; SDL_fatal_signals[i]; ++i ) {
   177 		ohandler = signal(SDL_fatal_signals[i], SIG_DFL);
   178 		if ( ohandler != SDL_Parachute ) {
   179 			signal(SDL_fatal_signals[i], ohandler);
   180 		}
   181 	}
   182 #endif /* HAVE_SIGACTION */
   183 }
   184 
   185 #endif /* NO_SIGNAL_H */