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