src/SDL_fatal.c
changeset 0 74212992fb08
child 1 cf2af46e9e2a
equal deleted inserted replaced
-1:000000000000 0:74212992fb08
       
     1 /*
       
     2     SDL - Simple DirectMedia Layer
       
     3     Copyright (C) 1997, 1998, 1999, 2000, 2001  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@devolution.com
       
    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 /* This installs some signal handlers for the more common fatal signals,
       
    55    so that if the programmer is lazy, the app doesn't die so horribly if
       
    56    the program crashes.
       
    57 */
       
    58 
       
    59 static void SDL_Parachute(int sig)
       
    60 {
       
    61 	signal(sig, SIG_DFL);
       
    62 	fprintf(stderr, "Fatal signal: ");
       
    63 	switch (sig) {
       
    64 		case SIGSEGV:
       
    65 			fprintf(stderr, "Segmentation Fault");
       
    66 			break;
       
    67 #ifdef SIGBUS
       
    68 #if SIGBUS != SIGSEGV
       
    69 		case SIGBUS:
       
    70 			fprintf(stderr, "Bus Error");
       
    71 			break;
       
    72 #endif
       
    73 #endif /* SIGBUS */
       
    74 #ifdef SIGFPE
       
    75 		case SIGFPE:
       
    76 			fprintf(stderr, "Floating Point Exception");
       
    77 			break;
       
    78 #endif /* SIGFPE */
       
    79 #ifdef SIGQUIT
       
    80 		case SIGQUIT:
       
    81 			fprintf(stderr, "Keyboard Quit");
       
    82 			break;
       
    83 #endif /* SIGQUIT */
       
    84 #ifdef SIGPIPE
       
    85 		case SIGPIPE:
       
    86 			fprintf(stderr, "Broken Pipe");
       
    87 			break;
       
    88 #endif /* SIGPIPE */
       
    89 		default:
       
    90 			fprintf(stderr, "# %d", sig);
       
    91 			break;
       
    92 	}
       
    93 	fprintf(stderr, " (SDL Parachute Deployed)\n");
       
    94 	SDL_Quit();
       
    95 	exit(-sig);
       
    96 }
       
    97 
       
    98 static int SDL_fatal_signals[] = {
       
    99 	SIGSEGV,
       
   100 #ifdef SIGBUS
       
   101 	SIGBUS,
       
   102 #endif
       
   103 #ifdef SIGFPE
       
   104 	SIGFPE,
       
   105 #endif
       
   106 #ifdef SIGQUIT
       
   107 	SIGQUIT,
       
   108 #endif
       
   109 #ifdef SIGPIPE
       
   110 	SIGPIPE,
       
   111 #endif
       
   112 	0
       
   113 };
       
   114 
       
   115 void SDL_InstallParachute(void)
       
   116 {
       
   117 	int i;
       
   118 	void (*ohandler)(int);
       
   119 
       
   120 	/* Set a handler for any fatal signal not already handled */
       
   121 	for ( i=0; SDL_fatal_signals[i]; ++i ) {
       
   122 		ohandler = signal(SDL_fatal_signals[i], SDL_Parachute);
       
   123 		if ( ohandler != SIG_DFL ) {
       
   124 			signal(SDL_fatal_signals[i], ohandler);
       
   125 		}
       
   126 	}
       
   127 #ifdef SIGALRM
       
   128 	/* Set SIGALRM to be ignored -- necessary on Solaris */
       
   129 	{
       
   130 		struct sigaction action, oaction;
       
   131 
       
   132 		/* Set SIG_IGN action */
       
   133 		memset(&action, 0, (sizeof action));
       
   134 		action.sa_handler = SIG_IGN;
       
   135 		sigaction(SIGALRM, &action, &oaction);
       
   136 
       
   137 		/* Reset original action if it was already being handled */
       
   138 		if ( oaction.sa_handler != SIG_DFL ) {
       
   139 			sigaction(SIGALRM, &oaction, NULL);
       
   140 		}
       
   141 	}
       
   142 #endif
       
   143 	return;
       
   144 }
       
   145 
       
   146 void SDL_UninstallParachute(void)
       
   147 {
       
   148 	int i;
       
   149 	void (*ohandler)(int);
       
   150 
       
   151 	/* Remove a handler for any fatal signal handled */
       
   152 	for ( i=0; SDL_fatal_signals[i]; ++i ) {
       
   153 		ohandler = signal(SDL_fatal_signals[i], SIG_DFL);
       
   154 		if ( ohandler != SDL_Parachute ) {
       
   155 			signal(SDL_fatal_signals[i], ohandler);
       
   156 		}
       
   157 	}
       
   158 }
       
   159 
       
   160 #endif /* NO_SIGNAL_H */