1 /* 2 * $DragonFly: src/games/larn/signal.c,v 1.4 2006/08/26 17:05:05 pavalos Exp $ 3 */ 4 5 #include <signal.h> 6 #include "header.h" /* "Larn is copyrighted 1986 by Noah Morgan.\n" */ 7 #define BIT(a) (1<<((a)-1)) 8 9 static void s2choose(void); 10 static void cntlc(void); 11 static void sgam(void); 12 #ifdef SIGTSTP 13 static void tstop(void); 14 #endif 15 static void sigill(void); 16 static void sigtrap(void); 17 static void sigiot(void); 18 static void sigemt(void); 19 static void sigfpe(void); 20 static void sigbus(void); 21 static void sigsegv(void); 22 static void sigsys(void); 23 static void sigpipe(void); 24 static void sigterm(void); 25 static void sigpanic(int); 26 27 static void 28 s2choose(void) /* text to be displayed if ^C during intro screen */ 29 { 30 cursor(1,24); lprcat("Press "); setbold(); lprcat("return"); resetbold(); 31 lprcat(" to continue: "); lflush(); 32 } 33 34 static void 35 cntlc(void) /* what to do for a ^C */ 36 { 37 if (nosignal) return; /* don't do anything if inhibited */ 38 signal(SIGQUIT,SIG_IGN); signal(SIGINT,SIG_IGN); 39 quit(); if (predostuff==1) s2choose(); else showplayer(); 40 lflush(); 41 signal(SIGQUIT,(sig_t)cntlc); signal(SIGINT,(sig_t)cntlc); 42 } 43 44 /* 45 * subroutine to save the game if a hangup signal 46 */ 47 static void 48 sgam(void) 49 { 50 savegame(savefilename); wizard=1; died(-257); /* hangup signal */ 51 } 52 53 #ifdef SIGTSTP 54 static void 55 tstop(void) /* control Y */ 56 { 57 if (nosignal) return; /* nothing if inhibited */ 58 lcreat(NULL); clearvt100(); lflush(); signal(SIGTSTP,SIG_DFL); 59 #ifdef SIGVTALRM 60 /* looks like BSD4.2 or higher - must clr mask for signal to take effect*/ 61 sigsetmask(sigblock(0)& ~BIT(SIGTSTP)); 62 #endif 63 kill(getpid(),SIGTSTP); 64 65 setupvt100(); signal(SIGTSTP,(sig_t)tstop); 66 if (predostuff==1) s2choose(); else drawscreen(); 67 showplayer(); lflush(); 68 } 69 #endif /* SIGTSTP */ 70 71 /* 72 * subroutine to issue the needed signal traps called from main() 73 */ 74 static void 75 sigill(void) 76 { sigpanic(SIGILL); } 77 78 static void 79 sigtrap(void) 80 { sigpanic(SIGTRAP); } 81 82 static void 83 sigiot(void) 84 { sigpanic(SIGIOT); } 85 86 static void 87 sigemt(void) 88 { sigpanic(SIGEMT); } 89 90 static void 91 sigfpe(void) 92 { sigpanic(SIGFPE); } 93 94 static void 95 sigbus(void) 96 { sigpanic(SIGBUS); } 97 98 static void 99 sigsegv(void) 100 { sigpanic(SIGSEGV); } 101 102 static void 103 sigsys(void) 104 { sigpanic(SIGSYS); } 105 106 static void 107 sigpipe(void) 108 { sigpanic(SIGPIPE); } 109 110 static void 111 sigterm(void) 112 { sigpanic(SIGTERM); } 113 114 void 115 sigsetup(void) 116 { 117 signal(SIGQUIT, (sig_t)cntlc); signal(SIGINT, (sig_t)cntlc); 118 signal(SIGKILL, SIG_IGN); signal(SIGHUP, (sig_t)sgam); 119 signal(SIGILL, (sig_t)sigill); signal(SIGTRAP, (sig_t)sigtrap); 120 signal(SIGIOT, (sig_t)sigiot); signal(SIGEMT, (sig_t)sigemt); 121 signal(SIGFPE, (sig_t)sigfpe); signal(SIGBUS, (sig_t)sigbus); 122 signal(SIGSEGV, (sig_t)sigsegv); signal(SIGSYS, (sig_t)sigsys); 123 signal(SIGPIPE, (sig_t)sigpipe); signal(SIGTERM, (sig_t)sigterm); 124 #ifdef SIGTSTP 125 signal(SIGTSTP, (sig_t)tstop); signal(SIGSTOP, (sig_t)tstop); 126 #endif /* SIGTSTP */ 127 } 128 129 #ifdef BSD /* for BSD UNIX? */ 130 131 static const char *signame[NSIG] = { "", 132 "SIGHUP", /* 1 hangup */ 133 "SIGINT", /* 2 interrupt */ 134 "SIGQUIT", /* 3 quit */ 135 "SIGILL", /* 4 illegal instruction (not reset when caught) */ 136 "SIGTRAP", /* 5 trace trap (not reset when caught) */ 137 "SIGIOT", /* 6 IOT instruction */ 138 "SIGEMT", /* 7 EMT instruction */ 139 "SIGFPE", /* 8 floating point exception */ 140 "SIGKILL", /* 9 kill (cannot be caught or ignored) */ 141 "SIGBUS", /* 10 bus error */ 142 "SIGSEGV", /* 11 segmentation violation */ 143 "SIGSYS", /* 12 bad argument to system call */ 144 "SIGPIPE", /* 13 write on a pipe with no one to read it */ 145 "SIGALRM", /* 14 alarm clock */ 146 "SIGTERM", /* 15 software termination signal from kill */ 147 "SIGURG", /* 16 urgent condition on IO channel */ 148 "SIGSTOP", /* 17 sendable stop signal not from tty */ 149 "SIGTSTP", /* 18 stop signal from tty */ 150 "SIGCONT", /* 19 continue a stopped process */ 151 "SIGCHLD", /* 20 to parent on child stop or exit */ 152 "SIGTTIN", /* 21 to readers pgrp upon background tty read */ 153 "SIGTTOU", /* 22 like TTIN for output if (tp->t_local<OSTOP) */ 154 "SIGIO", /* 23 input/output possible signal */ 155 "SIGXCPU", /* 24 exceeded CPU time limit */ 156 "SIGXFSZ", /* 25 exceeded file size limit */ 157 "SIGVTALRM",/* 26 virtual time alarm */ 158 "SIGPROF", /* 27 profiling time alarm */ 159 "","","","" }; 160 161 #else /* for system V? */ 162 163 static const char *signame[NSIG] = { "", 164 "SIGHUP", /* 1 hangup */ 165 "SIGINT", /* 2 interrupt */ 166 "SIGQUIT", /* 3 quit */ 167 "SIGILL", /* 4 illegal instruction (not reset when caught) */ 168 "SIGTRAP", /* 5 trace trap (not reset when caught) */ 169 "SIGIOT", /* 6 IOT instruction */ 170 "SIGEMT", /* 7 EMT instruction */ 171 "SIGFPE", /* 8 floating point exception */ 172 "SIGKILL", /* 9 kill (cannot be caught or ignored) */ 173 "SIGBUS", /* 10 bus error */ 174 "SIGSEGV", /* 11 segmentation violation */ 175 "SIGSYS", /* 12 bad argument to system call */ 176 "SIGPIPE", /* 13 write on a pipe with no one to read it */ 177 "SIGALRM", /* 14 alarm clock */ 178 "SIGTERM", /* 15 software termination signal from kill */ 179 "SIGUSR1", /* 16 user defines signal 1 */ 180 "SIGUSR2", /* 17 user defines signal 2 */ 181 "SIGCLD", /* 18 child death */ 182 "SIGPWR", /* 19 power fail */ 183 "","","","","","","","","","","","" }; 184 185 #endif /* BSD */ 186 187 /* 188 * routine to process a fatal error signal 189 */ 190 static void 191 sigpanic(int sig) 192 { 193 char buf[128]; 194 signal(sig,SIG_DFL); 195 sprintf(buf,"\nLarn - Panic! Signal %d received [%s]",sig,signame[sig]); 196 write(2,buf,strlen(buf)); sleep(2); 197 sncbr(); 198 savegame(savefilename); 199 kill(getpid(),sig); /* this will terminate us */ 200 } 201