src/SDL_fatal.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 04 Jan 2004 16:49:27 +0000
changeset 769 b8d311d90021
parent 297 f6ffac90895c
child 814 5a417d2a8603
permissions -rw-r--r--
Updated copyright information for 2004 (Happy New Year!)
     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 #ifdef SIGPIPE
   123 	SIGPIPE,
   124 #endif
   125 	0
   126 };
   127 
   128 void SDL_InstallParachute(void)
   129 {
   130 	int i;
   131 	void (*ohandler)(int);
   132 
   133 	/* Set a handler for any fatal signal not already handled */
   134 	for ( i=0; SDL_fatal_signals[i]; ++i ) {
   135 		ohandler = signal(SDL_fatal_signals[i], SDL_Parachute);
   136 		if ( ohandler != SIG_DFL ) {
   137 			signal(SDL_fatal_signals[i], ohandler);
   138 		}
   139 	}
   140 #ifdef SIGALRM
   141 	/* Set SIGALRM to be ignored -- necessary on Solaris */
   142 	{
   143 		struct sigaction action, oaction;
   144 
   145 		/* Set SIG_IGN action */
   146 		memset(&action, 0, (sizeof action));
   147 		action.sa_handler = SIG_IGN;
   148 		sigaction(SIGALRM, &action, &oaction);
   149 
   150 		/* Reset original action if it was already being handled */
   151 		if ( oaction.sa_handler != SIG_DFL ) {
   152 			sigaction(SIGALRM, &oaction, NULL);
   153 		}
   154 	}
   155 #endif
   156 	return;
   157 }
   158 
   159 void SDL_UninstallParachute(void)
   160 {
   161 	int i;
   162 	void (*ohandler)(int);
   163 
   164 	/* Remove a handler for any fatal signal handled */
   165 	for ( i=0; SDL_fatal_signals[i]; ++i ) {
   166 		ohandler = signal(SDL_fatal_signals[i], SIG_DFL);
   167 		if ( ohandler != SDL_Parachute ) {
   168 			signal(SDL_fatal_signals[i], ohandler);
   169 		}
   170 	}
   171 }
   172 
   173 #endif /* NO_SIGNAL_H */