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 17static void s2choose(void); 18static void cntlc(int); 19static void sgam(int); 20static void tstop(int); 21static void sigpanic(int); 22 23#define BIT(a) (1<<((a)-1)) 24 25static void 26s2choose(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 38static void 39cntlc(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 */ 58static void 59sgam(int n) 60{ 61 savegame(savefilename); 62 wizard = 1; 63 died(-257); /* hangup signal */ 64} 65 66#ifdef SIGTSTP 67static void 68tstop(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 */ 99void 100sigsetup(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 */ 125static void 126sigpanic(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