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