src/SDL_fatal.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 26 Feb 2004 19:57:37 +0000
changeset 861 863da1c38c7e
parent 822 abb915adb1b0
child 1152 51a8702d8ecd
permissions -rw-r--r--
Oops, ignore SIGALRM, not 0
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2004 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 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     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 
    23 #ifdef SAVE_RCSID
    24 static char rcsid =
    25  "@(#) $Id$";
    26 #endif
    27 
    28 /* General fatal signal handling code for SDL */
    29 
    30 #ifdef NO_SIGNAL_H
    31 
    32 /* No signals on this platform, nothing to do.. */
    33 
    34 void SDL_InstallParachute(void)
    35 {
    36 	return;
    37 }
    38 
    39 void SDL_UninstallParachute(void)
    40 {
    41 	return;
    42 }
    43 
    44 #else
    45 
    46 #include <stdlib.h>
    47 #include <stdio.h>
    48 #include <signal.h>
    49 #include <string.h>
    50 
    51 #include "SDL.h"
    52 #include "SDL_fatal.h"
    53 
    54 #ifdef __CYGWIN__
    55 #define DISABLE_STDIO
    56 #endif
    57 
    58 /* This installs some signal handlers for the more common fatal signals,
    59    so that if the programmer is lazy, the app doesn't die so horribly if
    60    the program crashes.
    61 */
    62 
    63 static void print_msg(const char *text)
    64 {
    65 #ifndef DISABLE_STDIO
    66 	fprintf(stderr, "%s", text);
    67 #endif
    68 }
    69 
    70 static void SDL_Parachute(int sig)
    71 {
    72 	signal(sig, SIG_DFL);
    73 	print_msg("Fatal signal: ");
    74 	switch (sig) {
    75 		case SIGSEGV:
    76 			print_msg("Segmentation Fault");
    77 			break;
    78 #ifdef SIGBUS
    79 #if SIGBUS != SIGSEGV
    80 		case SIGBUS:
    81 			print_msg("Bus Error");
    82 			break;
    83 #endif
    84 #endif /* SIGBUS */
    85 #ifdef SIGFPE
    86 		case SIGFPE:
    87 			print_msg("Floating Point Exception");
    88 			break;
    89 #endif /* SIGFPE */
    90 #ifdef SIGQUIT
    91 		case SIGQUIT:
    92 			print_msg("Keyboard Quit");
    93 			break;
    94 #endif /* SIGQUIT */
    95 #ifdef SIGPIPE
    96 		case SIGPIPE:
    97 			print_msg("Broken Pipe");
    98 			break;
    99 #endif /* SIGPIPE */
   100 		default:
   101 #ifndef DISABLE_STDIO
   102 			fprintf(stderr, "# %d", sig);
   103 #endif
   104 			break;
   105 	}
   106 	print_msg(" (SDL Parachute Deployed)\n");
   107 	SDL_Quit();
   108 	exit(-sig);
   109 }
   110 
   111 static int SDL_fatal_signals[] = {
   112 	SIGSEGV,
   113 #ifdef SIGBUS
   114 	SIGBUS,
   115 #endif
   116 #ifdef SIGFPE
   117 	SIGFPE,
   118 #endif
   119 #ifdef SIGQUIT
   120 	SIGQUIT,
   121 #endif
   122 	0
   123 };
   124 
   125 void SDL_InstallParachute(void)
   126 {
   127 	/* Set a handler for any fatal signal not already handled */
   128 	int i;
   129 #ifdef HAVE_SIGACTION
   130 	struct sigaction action;
   131 
   132 	for ( i=0; SDL_fatal_signals[i]; ++i ) {
   133 		sigaction(SDL_fatal_signals[i], NULL, &action);
   134 		if ( action.sa_handler == SIG_DFL ) {
   135 			action.sa_handler = SDL_Parachute;
   136 			sigaction(SDL_fatal_signals[i], &action, NULL);
   137 		}
   138 	}
   139 #ifdef SIGALRM
   140 	/* Set SIGALRM to be ignored -- necessary on Solaris */
   141 	sigaction(SIGALRM, NULL, &action);
   142 	if ( action.sa_handler == SIG_DFL ) {
   143 		action.sa_handler = SIG_IGN;
   144 		sigaction(SIGALRM, &action, NULL);
   145 	}
   146 #endif
   147 #else
   148 	void (*ohandler)(int);
   149 
   150 	for ( i=0; SDL_fatal_signals[i]; ++i ) {
   151 		ohandler = signal(SDL_fatal_signals[i], SDL_Parachute);
   152 		if ( ohandler != SIG_DFL ) {
   153 			signal(SDL_fatal_signals[i], ohandler);
   154 		}
   155 	}
   156 #endif /* HAVE_SIGACTION */
   157 	return;
   158 }
   159 
   160 void SDL_UninstallParachute(void)
   161 {
   162 	/* Remove a handler for any fatal signal handled */
   163 	int i;
   164 #ifdef HAVE_SIGACTION
   165 	struct sigaction action;
   166 
   167 	for ( i=0; SDL_fatal_signals[i]; ++i ) {
   168 		sigaction(SDL_fatal_signals[i], NULL, &action);
   169 		if ( action.sa_handler == SDL_Parachute ) {
   170 			action.sa_handler = SIG_DFL;
   171 			sigaction(SDL_fatal_signals[i], &action, NULL);
   172 		}
   173 	}
   174 #else
   175 	void (*ohandler)(int);
   176 
   177 	for ( i=0; SDL_fatal_signals[i]; ++i ) {
   178 		ohandler = signal(SDL_fatal_signals[i], SIG_DFL);
   179 		if ( ohandler != SDL_Parachute ) {
   180 			signal(SDL_fatal_signals[i], ohandler);
   181 		}
   182 	}
   183 #endif /* HAVE_SIGACTION */
   184 }
   185 
   186 #endif /* NO_SIGNAL_H */