1 /* $NetBSD: signal.c,v 1.8 2004/01/27 20:30:30 jsm Exp $ */ 2 3 /* "Larn is copyrighted 1986 by Noah Morgan.\n" */ 4 5 #include <sys/cdefs.h> 6 #ifndef lint 7 __RCSID("$NetBSD: signal.c,v 1.8 2004/01/27 20:30:30 jsm Exp $"); 8 #endif /* not lint */ 9 10 #include <signal.h> 11 #include <stdio.h> 12 #include <string.h> 13 #include <unistd.h> 14 #include "header.h" 15 #include "extern.h" 16 17 static void s2choose(void); 18 static void cntlc(int); 19 static void sgam(int); 20 static void tstop(int); 21 static void sigpanic(int); 22 23 #define BIT(a) (1<<((a)-1)) 24 25 static void 26 s2choose() 27 { /* text to be displayed if ^C during intro 28 * screen */ 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(n) 40 int n; 41 { /* what to do for a ^C */ 42 if (nosignal) 43 return; /* don't do anything if inhibited */ 44 signal(SIGQUIT, SIG_IGN); 45 signal(SIGINT, SIG_IGN); 46 quit(); 47 if (predostuff == 1) 48 s2choose(); 49 else 50 showplayer(); 51 lflush(); 52 signal(SIGQUIT, cntlc); 53 signal(SIGINT, cntlc); 54 } 55 56 /* 57 * subroutine to save the game if a hangup signal 58 */ 59 static void 60 sgam(n) 61 int n; 62 { 63 savegame(savefilename); 64 wizard = 1; 65 died(-257); /* hangup signal */ 66 } 67 68 #ifdef SIGTSTP 69 static void 70 tstop(n) 71 int n; 72 { /* control Y */ 73 if (nosignal) 74 return; /* nothing if inhibited */ 75 lcreat((char *) 0); 76 clearvt100(); 77 lflush(); 78 signal(SIGTSTP, SIG_DFL); 79 #ifdef SIGVTALRM 80 /* 81 * looks like BSD4.2 or higher - must clr mask for signal to take 82 * effect 83 */ 84 sigsetmask(sigblock(0) & ~BIT(SIGTSTP)); 85 #endif 86 kill(getpid(), SIGTSTP); 87 88 setupvt100(); 89 signal(SIGTSTP, tstop); 90 if (predostuff == 1) 91 s2choose(); 92 else 93 drawscreen(); 94 showplayer(); 95 lflush(); 96 } 97 #endif /* SIGTSTP */ 98 99 /* 100 * subroutine to issue the needed signal traps called from main() 101 */ 102 void 103 sigsetup() 104 { 105 signal(SIGQUIT, cntlc); 106 signal(SIGINT, cntlc); 107 signal(SIGKILL, SIG_IGN); 108 signal(SIGHUP, sgam); 109 signal(SIGILL, sigpanic); 110 signal(SIGTRAP, sigpanic); 111 signal(SIGIOT, sigpanic); 112 signal(SIGEMT, sigpanic); 113 signal(SIGFPE, sigpanic); 114 signal(SIGBUS, sigpanic); 115 signal(SIGSEGV, sigpanic); 116 signal(SIGSYS, sigpanic); 117 signal(SIGPIPE, sigpanic); 118 signal(SIGTERM, sigpanic); 119 #ifdef SIGTSTP 120 signal(SIGTSTP, tstop); 121 signal(SIGSTOP, tstop); 122 #endif /* SIGTSTP */ 123 } 124 125 /* 126 * routine to process a fatal error signal 127 */ 128 static void 129 sigpanic(sig) 130 int sig; 131 { 132 char buf[128]; 133 signal(sig, SIG_DFL); 134 snprintf(buf, sizeof(buf), 135 "\nLarn - Panic! Signal %d received [SIG%s]", sig, 136 sys_signame[sig]); 137 write(2, buf, strlen(buf)); 138 sleep(2); 139 sncbr(); 140 savegame(savefilename); 141 kill(getpid(), sig); /* this will terminate us */ 142 } 143