1 /* Header: /usr/src/games/warp/RCS/sig.c,v 1.1 87/07/03 01:47:11 games Exp */ 2 3 /* Log: sig.c,v 4 * Revision 7.0.1.1a 87/07/03 01:47:11 games 5 * Changed sigsetmask to use sigmask instead of calculating it (incorrectly) 6 * by hand. 7 * 8 * Revision 7.0.1.1 86/12/12 17:02:44 lwall 9 * Baseline for net release. 10 * 11 * Revision 7.0 86/10/08 15:13:24 lwall 12 * Split into separate files. Added amoebas and pirates. 13 * 14 */ 15 16 #include "EXTERN.h" 17 #include "warp.h" 18 #include "play.h" 19 #include "score.h" 20 #include "term.h" 21 #include "util.h" 22 #include "INTERN.h" 23 #include "sig.h" 24 25 void 26 sig_init() 27 { 28 #ifdef lint 29 ; 30 #else 31 sigignore(SIGINT); /* for inquiry of existence via kill call */ 32 #ifdef SIGTTOU 33 sigignore(SIGTTOU); 34 #endif 35 36 sigset(SIGHUP, sig_catcher); 37 if (!debugging) { 38 sigset(SIGQUIT, sig_catcher); 39 sigset(SIGILL, sig_catcher); 40 sigset(SIGFPE, sig_catcher); 41 sigset(SIGBUS, sig_catcher); 42 sigset(SIGSEGV, sig_catcher); 43 sigset(SIGSYS, sig_catcher); 44 sigset(SIGTERM, sig_catcher); 45 } 46 #ifdef SIGXCPU 47 sigset(SIGXCPU, sig_catcher); 48 #endif 49 #ifdef SIGCONT 50 sigset(SIGCONT, cont_catcher); 51 #endif 52 #ifdef SIGTSTP 53 sigset(SIGTSTP, stop_catcher); 54 sigset(SIGSTOP, stop_catcher); 55 #endif 56 #endif /* lint */ 57 } 58 59 #ifdef SIGTSTP 60 void 61 cont_catcher(int x) 62 { 63 #ifndef lint 64 sigset(SIGCONT,cont_catcher); 65 #endif 66 savetty(); 67 crmode(); 68 raw(); 69 noecho(); 70 nonl(); 71 } 72 #endif 73 74 void 75 mytstp() 76 { 77 resetty(); 78 #ifdef SIGTSTP 79 kill(0,SIGTSTP); 80 #else 81 if (fork()) 82 wait(0); 83 else { 84 char *shell = getenv("SHELL"); 85 86 setuid(getuid()); 87 if (!*shell) 88 shell = "/bin/sh"; 89 execl(shell,shell,0); 90 exit(1); 91 } 92 #endif 93 rewrite(); 94 } 95 96 void /* very much void */ 97 finalize(status) 98 int status; 99 { 100 if (bizarre) 101 resetty(); 102 if (status < 0) { 103 chdir("/usr/tmp"); 104 sigset(SIGILL,SIG_DFL); 105 abort(); 106 } 107 exit(status); 108 } 109 110 /* come here on signal other than interrupt, stop, or cont */ 111 112 void 113 sig_catcher(int signo) 114 { 115 #ifdef VERBOSE 116 static char *signame[] = { 117 "", 118 "HUP", 119 "INT", 120 "QUIT", 121 "ILL", 122 "TRAP", 123 "IOT", 124 "EMT", 125 "FPE", 126 "KILL", 127 "BUS", 128 "SEGV", 129 "SYS", 130 "PIPE", 131 "ALRM", 132 "TERM", 133 "???" 134 #ifdef SIGTSTP 135 ,"STOP", 136 "TSTP", 137 "CONT", 138 "CHLD", 139 "TTIN", 140 "TTOU", 141 "TINT", 142 "XCPU", 143 "XFSZ" 144 #ifdef SIGPROF 145 ,"VTALARM", 146 "PROF" 147 #endif 148 #endif 149 }; 150 #endif 151 152 #ifdef SIGTTOU 153 #ifndef lint 154 sigignore(SIGTTOU); 155 #endif /* lint */ 156 #endif 157 #ifdef DEBUGGING 158 if (debug) { 159 printf("\r\nSIG%s--game not saved in debug\r\n",signame[signo]); 160 finalize(-1); 161 } 162 #endif 163 panic++; 164 if (panic >= 2) { 165 if (panic >= 3) 166 abort(); 167 chdir(SAVEDIR); 168 kill(0,SIGIOT); 169 } 170 (void) sigset(SIGILL,SIG_DFL); 171 if (signo == SIGHUP && (timer < 10 || didkill)) 172 signo = SIGQUIT; 173 if (signo == SIGQUIT) { /* can't let them bomb out without penalty */ 174 if (smarts < 20) 175 smarts += 4; 176 else if (smarts < 35) 177 smarts += 2; 178 else 179 smarts++; 180 totalscore -= possiblescore / 2; 181 } 182 save_game(); 183 if (signo != SIGHUP && signo != SIGQUIT) 184 #ifdef VERBOSE 185 IF(verbose) 186 printf("\r\nCaught %s%s--%s\r\n", 187 signo ? "a SIG" : "an internal error", signame[signo], 188 experimenting ? "game saved" : "bye bye"); 189 ELSE 190 #endif 191 #ifdef TERSE 192 printf("\r\nSignal %d--bye bye\r\n",signo); 193 #endif 194 switch (signo) { 195 case SIGBUS: 196 case SIGILL: 197 case SIGSEGV: 198 finalize(-signo); 199 } 200 finalize(1); /* and blow up */ 201 } 202 203 #ifdef SIGTSTP 204 /* come here on stop signal */ 205 206 void 207 stop_catcher(int sig) 208 { 209 if (!waiting) { 210 resetty(); /* this is the point of all this */ 211 #ifdef DEBUGGING 212 if (debug) 213 write(2,"stop_catcher\r\n",13); 214 #endif 215 sigset(SIGTSTP,SIG_DFL); /* enable stop */ 216 #ifdef BSD42 217 sigsetmask(sigblock(0L) & ~sigmask(SIGTSTP)); 218 #endif 219 kill(0,SIGTSTP); /* and do the stop */ 220 } 221 #ifndef lint 222 sigset(SIGTSTP,stop_catcher); /* unenable the stop */ 223 #endif 224 } 225 #endif 226