/* * signals.c: signal handlers * * Copyright (c) 1989 James E. Wilson * * This software may be copied and distributed for educational, research, and * not for profit purposes provided that this copyright and statement are * included in all such copies. */ /* This signal package was brought to you by -JEW- */ /* Completely rewritten by -CJS- */ /* Signals have no significance on the Mac */ #ifdef MAC void nosignals() { } void signals() { } void init_signals() { } #else /* a non-Mac system */ #include #ifdef linux #define SIGBUS SIGUSR1 #endif #ifdef ATARIST_MWC /* * need these for atari st, but for unix, must include signals.h first, or * else suspend won't be properly declared */ #include "constant.h" #include "config.h" #include "types.h" #include "externs.h" #endif /* skip most of the file on an ATARI ST */ #ifndef ATARIST_MWC /* to get the SYS_V def if needed */ #include "config.h" #if defined(SYS_V) && defined(lint) /* * for AIX, prevent hundreds of unnecessary lint errors, define before * signal.h is included */ #define _h_IEEETRAP typedef struct { int stuff; } fpvmach; #endif /* must include before externs.h, because that uses SIGTSTP */ #include #include "constant.h" #include "types.h" #include "externs.h" #ifndef USG /* only needed for Berkeley UNIX */ #include #include #endif #ifdef USG #ifndef ATARIST_MWC #include #endif #else #ifndef VMS #include #endif #endif #ifdef USG void exit(); #ifdef __TURBOC__ void sleep(); #else unsigned sleep(); #endif #endif static int error_sig = (-1); static int signal_count = 0; /* ARGSUSED */ #ifndef USG static void signal_handler(sig, code, scp) int sig, code; struct sigcontext *scp; { int smask; smask = sigsetmask(0) | (1 << sig); #else #ifdef __TURBOC__ static void signal_handler(sig) #else static void signal_handler(sig) #endif int sig; { #endif if (error_sig >= 0) { /* Ignore all second signals. */ if (++signal_count > 10) /* Be safe. We will die if persistent * enough. */ (void)signal(sig, SIG_DFL); return; } error_sig = sig; /* Allow player to think twice. Wizard may force a core dump. */ if (sig == SIGINT #ifndef MSDOS || sig == SIGQUIT #endif ) { if (death) (void)signal(sig, SIG_IGN); /* Can't quit after death. */ else if (!character_saved && character_generated) { if ((!total_winner) ? (!get_Yn("Really commit *Suicide*?")) : (!get_Yn("Do you want to retire?"))) { if (turn > 0) disturb(1, 0); erase_line(0, 0); put_qio(); error_sig = (-1); #ifdef USG #ifdef linux (void) signal(sig, (void (*)()) signal_handler); #else (void) signal(sig, signal_handler);/* Have to restore handler.*/ #endif #else (void)sigsetmask(smask); #endif /* in case control-c typed during msg_print */ if (wait_for_more) put_buffer(" -more-", MSG_LINE, 0); put_qio(); return; /* OK. We don't quit. */ } (void)strcpy(died_from, "Interrupting"); } else (void)strcpy(died_from, "Abortion"); prt("Interrupt!", 0, 0); death = TRUE; exit_game(); } /* Die. */ prt( "OH NO!!!!!! A gruesome software bug LEAPS out at you. There is NO defense!", 23, 0); if (!death && !character_saved && character_generated) { panic_save = 1; prt("Your guardian angel is trying to save you.", 0, 0); (void)sprintf(died_from, "(panic save %d)", sig); if (!save_char()) { (void)strcpy(died_from, "software bug"); death = TRUE; turn = (-1); } } else { death = TRUE; (void)_save_char(savefile);/* Quietly save the memory anyway. */ } restore_term(); #ifndef MSDOS /* always generate a core dump */ (void)signal(sig, SIG_DFL); (void)kill(getpid(), sig); (void)sleep(5); #endif exit(1); } #endif /* ATARIST_MWC */ #ifdef ATARIST_MWC static int error_sig = (-1); #endif #ifndef USG static int mask; #endif void nosignals() { #if !defined(ATARIST_MWC) #ifdef SIGTSTP #ifdef linux (void) signal(SIGTSTP, (void (*)()) suspend); #else (void)signal(SIGTSTP, SIG_IGN); #endif #ifndef USG mask = sigsetmask(0); #endif #endif if (error_sig < 0) error_sig = 0; #endif } void signals() { #if !defined(ATARIST_MWC) #ifdef SIGTSTP #ifdef __MINT__ (void)signal(SIGTSTP, (__Sigfunc)suspend); #else (void)signal(SIGTSTP, suspend); #endif #ifndef USG (void)sigsetmask(mask); #endif #endif if (error_sig == 0) error_sig = (-1); #endif } void init_signals() { #ifndef ATARIST_MWC #ifdef linux (void) signal(SIGINT, (void (*)()) signal_handler); (void) signal(SIGFPE, (void (*)()) signal_handler); #else (void)signal(SIGINT, signal_handler); (void)signal(SIGFPE, signal_handler); #endif #ifdef MSDOS /* many fewer signals under MSDOS */ #else /* Ignore HANGUP, and let the EOF code take care of this case. */ (void)signal(SIGHUP, SIG_IGN); #ifdef linux (void) signal(SIGQUIT, (void (*)()) signal_handler); (void) signal(SIGILL, (void (*)()) signal_handler); (void) signal(SIGTRAP, (void (*)()) signal_handler); (void) signal(SIGIOT, (void (*)()) signal_handler); #else (void)signal(SIGQUIT, signal_handler); (void)signal(SIGILL, signal_handler); (void)signal(SIGTRAP, signal_handler); (void)signal(SIGIOT, signal_handler); #endif #ifdef SIGEMT /* in BSD systems */ #ifdef linux (void) signal(SIGEMT, (void (*)()) signal_handler); #else (void)signal(SIGEMT, signal_handler); #endif #endif #ifdef SIGDANGER /* in SYSV systems */ #ifdef linux (void) signal(SIGDANGER, (void (*)()) signal_handler); #else (void)signal(SIGDANGER, signal_handler); #endif #endif #ifdef linux (void) signal(SIGKILL, (void (*)()) signal_handler); (void) signal(SIGBUS, (void (*)()) signal_handler); (void) signal(SIGSEGV, (void (*)()) signal_handler); #ifdef SIGSYS (void) signal(SIGSYS, (void (*)()) signal_handler); #endif (void) signal(SIGTERM, (void (*)()) signal_handler); (void) signal(SIGPIPE, (void (*)()) signal_handler); #else (void)signal(SIGKILL, signal_handler); (void)signal(SIGBUS, signal_handler); (void)signal(SIGSEGV, signal_handler); /* (void)signal(SIGSYS, signal_handler); not in linux pgb */ (void)signal(SIGTERM, signal_handler); (void)signal(SIGPIPE, signal_handler); #endif #ifdef SIGXCPU /* BSD */ #ifdef linux (void) signal(SIGXCPU, (void (*)()) signal_handler); #else (void)signal(SIGXCPU, signal_handler); #endif #endif #ifdef SIGPWR /* SYSV */ #ifdef linux (void) signal(SIGPWR, (void (*)()) signal_handler); #else (void)signal(SIGPWR, signal_handler); #endif #endif #endif #endif } void ignore_signals() { #if !defined(ATARIST_MWC) (void)signal(SIGINT, SIG_IGN); #ifdef SIGQUIT (void)signal(SIGQUIT, SIG_IGN); #endif #endif } void default_signals() { #if !defined(ATARIST_MWC) (void)signal(SIGINT, SIG_DFL); #ifdef SIGQUIT (void)signal(SIGQUIT, SIG_DFL); #endif #endif } void restore_signals() { #if !defined(ATARIST_MWC) #ifndef linux (void)signal(SIGINT, signal_handler); #endif /* linux */ #ifdef SIGQUIT #ifdef linux (void) signal(SIGQUIT, (void (*)()) signal_handler); #else (void)signal(SIGQUIT, signal_handler); #endif #endif #endif } #endif /* big Mac conditional */