1 /* $NetBSD: signal.c,v 1.9 2012/06/19 05:30:44 dholland 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.9 2012/06/19 05:30:44 dholland 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(void) 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(int n) 40 { /* what to do for a ^C */ 41 if (nosignal) 42 return; /* don't do anything if inhibited */ 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(int n) 60 { 61 savegame(savefilename); 62 wizard = 1; 63 died(-257); /* hangup signal */ 64 } 65 66 #ifdef SIGTSTP 67 static void 68 tstop(int n) 69 { /* control Y */ 70 if (nosignal) 71 return; /* nothing if inhibited */ 72 lcreat((char *) 0); 73 clearvt100(); 74 lflush(); 75 signal(SIGTSTP, SIG_DFL); 76 #ifdef SIGVTALRM 77 /* 78 * looks like BSD4.2 or higher - must clr mask for signal to take 79 * effect 80 */ 81 sigsetmask(sigblock(0) & ~BIT(SIGTSTP)); 82 #endif 83 kill(getpid(), SIGTSTP); 84 85 setupvt100(); 86 signal(SIGTSTP, 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 void 100 sigsetup(void) 101 { 102 signal(SIGQUIT, cntlc); 103 signal(SIGINT, cntlc); 104 signal(SIGKILL, SIG_IGN); 105 signal(SIGHUP, sgam); 106 signal(SIGILL, sigpanic); 107 signal(SIGTRAP, sigpanic); 108 signal(SIGIOT, sigpanic); 109 signal(SIGEMT, sigpanic); 110 signal(SIGFPE, sigpanic); 111 signal(SIGBUS, sigpanic); 112 signal(SIGSEGV, sigpanic); 113 signal(SIGSYS, sigpanic); 114 signal(SIGPIPE, sigpanic); 115 signal(SIGTERM, sigpanic); 116 #ifdef SIGTSTP 117 signal(SIGTSTP, tstop); 118 signal(SIGSTOP, tstop); 119 #endif /* SIGTSTP */ 120 } 121 122 /* 123 * routine to process a fatal error signal 124 */ 125 static void 126 sigpanic(int sig) 127 { 128 char buf[128]; 129 signal(sig, SIG_DFL); 130 snprintf(buf, sizeof(buf), 131 "\nLarn - Panic! Signal %d received [SIG%s]", sig, 132 sys_signame[sig]); 133 write(2, buf, strlen(buf)); 134 sleep(2); 135 sncbr(); 136 savegame(savefilename); 137 kill(getpid(), sig); /* this will terminate us */ 138 } 139