src/SDL_fatal.c
author Sam Lantinga <slouken@lokigames.com>
Thu, 26 Apr 2001 16:45:43 +0000
changeset 0 74212992fb08
child 1 cf2af46e9e2a
permissions -rw-r--r--
Initial revision
     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 */