Mercurial > sdl-ios-xcode
diff src/SDL_fatal.c @ 0:74212992fb08
Initial revision
author | Sam Lantinga <slouken@lokigames.com> |
---|---|
date | Thu, 26 Apr 2001 16:45:43 +0000 |
parents | |
children | cf2af46e9e2a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/SDL_fatal.c Thu Apr 26 16:45:43 2001 +0000 @@ -0,0 +1,160 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* General fatal signal handling code for SDL */ + +#ifdef NO_SIGNAL_H + +/* No signals on this platform, nothing to do.. */ + +void SDL_InstallParachute(void) +{ + return; +} + +void SDL_UninstallParachute(void) +{ + return; +} + +#else + +#include <stdlib.h> +#include <stdio.h> +#include <signal.h> +#include <string.h> + +#include "SDL.h" +#include "SDL_fatal.h" + +/* This installs some signal handlers for the more common fatal signals, + so that if the programmer is lazy, the app doesn't die so horribly if + the program crashes. +*/ + +static void SDL_Parachute(int sig) +{ + signal(sig, SIG_DFL); + fprintf(stderr, "Fatal signal: "); + switch (sig) { + case SIGSEGV: + fprintf(stderr, "Segmentation Fault"); + break; +#ifdef SIGBUS +#if SIGBUS != SIGSEGV + case SIGBUS: + fprintf(stderr, "Bus Error"); + break; +#endif +#endif /* SIGBUS */ +#ifdef SIGFPE + case SIGFPE: + fprintf(stderr, "Floating Point Exception"); + break; +#endif /* SIGFPE */ +#ifdef SIGQUIT + case SIGQUIT: + fprintf(stderr, "Keyboard Quit"); + break; +#endif /* SIGQUIT */ +#ifdef SIGPIPE + case SIGPIPE: + fprintf(stderr, "Broken Pipe"); + break; +#endif /* SIGPIPE */ + default: + fprintf(stderr, "# %d", sig); + break; + } + fprintf(stderr, " (SDL Parachute Deployed)\n"); + SDL_Quit(); + exit(-sig); +} + +static int SDL_fatal_signals[] = { + SIGSEGV, +#ifdef SIGBUS + SIGBUS, +#endif +#ifdef SIGFPE + SIGFPE, +#endif +#ifdef SIGQUIT + SIGQUIT, +#endif +#ifdef SIGPIPE + SIGPIPE, +#endif + 0 +}; + +void SDL_InstallParachute(void) +{ + int i; + void (*ohandler)(int); + + /* Set a handler for any fatal signal not already handled */ + for ( i=0; SDL_fatal_signals[i]; ++i ) { + ohandler = signal(SDL_fatal_signals[i], SDL_Parachute); + if ( ohandler != SIG_DFL ) { + signal(SDL_fatal_signals[i], ohandler); + } + } +#ifdef SIGALRM + /* Set SIGALRM to be ignored -- necessary on Solaris */ + { + struct sigaction action, oaction; + + /* Set SIG_IGN action */ + memset(&action, 0, (sizeof action)); + action.sa_handler = SIG_IGN; + sigaction(SIGALRM, &action, &oaction); + + /* Reset original action if it was already being handled */ + if ( oaction.sa_handler != SIG_DFL ) { + sigaction(SIGALRM, &oaction, NULL); + } + } +#endif + return; +} + +void SDL_UninstallParachute(void) +{ + int i; + void (*ohandler)(int); + + /* Remove a handler for any fatal signal handled */ + for ( i=0; SDL_fatal_signals[i]; ++i ) { + ohandler = signal(SDL_fatal_signals[i], SIG_DFL); + if ( ohandler != SDL_Parachute ) { + signal(SDL_fatal_signals[i], ohandler); + } + } +} + +#endif /* NO_SIGNAL_H */