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