signal.c revision 1.4 1 1.2 mycroft #ifndef lint
2 1.4 cgd static char rcsid[] = "$NetBSD: signal.c,v 1.4 1995/04/24 12:24:12 cgd Exp $";
3 1.2 mycroft #endif /* not lint */
4 1.2 mycroft
5 1.1 cgd #include <signal.h>
6 1.1 cgd #include "header.h" /* "Larn is copyrighted 1986 by Noah Morgan.\n" */
7 1.4 cgd #include <string.h>
8 1.4 cgd
9 1.1 cgd #define BIT(a) (1<<((a)-1))
10 1.1 cgd extern char savefilename[],wizard,predostuff,nosignal;
11 1.1 cgd static s2choose() /* text to be displayed if ^C during intro screen */
12 1.1 cgd {
13 1.1 cgd cursor(1,24); lprcat("Press "); setbold(); lprcat("return"); resetbold();
14 1.1 cgd lprcat(" to continue: "); lflush();
15 1.1 cgd }
16 1.1 cgd
17 1.1 cgd static void
18 1.1 cgd cntlc() /* what to do for a ^C */
19 1.1 cgd {
20 1.1 cgd if (nosignal) return; /* don't do anything if inhibited */
21 1.1 cgd signal(SIGQUIT,SIG_IGN); signal(SIGINT,SIG_IGN);
22 1.1 cgd quit(); if (predostuff==1) s2choose(); else showplayer();
23 1.1 cgd lflush();
24 1.1 cgd signal(SIGQUIT,cntlc); signal(SIGINT,cntlc);
25 1.1 cgd }
26 1.1 cgd
27 1.1 cgd /*
28 1.1 cgd * subroutine to save the game if a hangup signal
29 1.1 cgd */
30 1.1 cgd static void
31 1.1 cgd sgam()
32 1.1 cgd {
33 1.1 cgd savegame(savefilename); wizard=1; died(-257); /* hangup signal */
34 1.1 cgd }
35 1.1 cgd
36 1.1 cgd #ifdef SIGTSTP
37 1.1 cgd static void
38 1.1 cgd tstop() /* control Y */
39 1.1 cgd {
40 1.1 cgd if (nosignal) return; /* nothing if inhibited */
41 1.1 cgd lcreat((char*)0); clearvt100(); lflush(); signal(SIGTSTP,SIG_DFL);
42 1.1 cgd #ifdef SIGVTALRM
43 1.1 cgd /* looks like BSD4.2 or higher - must clr mask for signal to take effect*/
44 1.1 cgd sigsetmask(sigblock(0)& ~BIT(SIGTSTP));
45 1.1 cgd #endif
46 1.1 cgd kill(getpid(),SIGTSTP);
47 1.1 cgd
48 1.1 cgd setupvt100(); signal(SIGTSTP,tstop);
49 1.1 cgd if (predostuff==1) s2choose(); else drawscreen();
50 1.1 cgd showplayer(); lflush();
51 1.1 cgd }
52 1.1 cgd #endif SIGTSTP
53 1.1 cgd
54 1.1 cgd /*
55 1.1 cgd * subroutine to issue the needed signal traps called from main()
56 1.1 cgd */
57 1.1 cgd static void sigpanic();
58 1.1 cgd static void sigill() { sigpanic(SIGILL); }
59 1.1 cgd static void sigtrap() { sigpanic(SIGTRAP); }
60 1.1 cgd static void sigiot() { sigpanic(SIGIOT); }
61 1.1 cgd static void sigemt() { sigpanic(SIGEMT); }
62 1.1 cgd static void sigfpe() { sigpanic(SIGFPE); }
63 1.1 cgd static void sigbus() { sigpanic(SIGBUS); }
64 1.1 cgd static void sigsegv() { sigpanic(SIGSEGV); }
65 1.1 cgd static void sigsys() { sigpanic(SIGSYS); }
66 1.1 cgd static void sigpipe() { sigpanic(SIGPIPE); }
67 1.1 cgd static void sigterm() { sigpanic(SIGTERM); }
68 1.1 cgd sigsetup()
69 1.1 cgd {
70 1.1 cgd signal(SIGQUIT, cntlc); signal(SIGINT, cntlc);
71 1.1 cgd signal(SIGKILL, SIG_IGN); signal(SIGHUP, sgam);
72 1.1 cgd signal(SIGILL, sigill); signal(SIGTRAP, sigtrap);
73 1.1 cgd signal(SIGIOT, sigiot); signal(SIGEMT, sigemt);
74 1.1 cgd signal(SIGFPE, sigfpe); signal(SIGBUS, sigbus);
75 1.1 cgd signal(SIGSEGV, sigsegv); signal(SIGSYS, sigsys);
76 1.1 cgd signal(SIGPIPE, sigpipe); signal(SIGTERM, sigterm);
77 1.1 cgd #ifdef SIGTSTP
78 1.1 cgd signal(SIGTSTP,tstop); signal(SIGSTOP,tstop);
79 1.1 cgd #endif SIGTSTP
80 1.1 cgd }
81 1.1 cgd
82 1.1 cgd #ifdef BSD /* for BSD UNIX? */
83 1.1 cgd
84 1.1 cgd static char *signame[NSIG] = { "",
85 1.1 cgd "SIGHUP", /* 1 hangup */
86 1.1 cgd "SIGINT", /* 2 interrupt */
87 1.1 cgd "SIGQUIT", /* 3 quit */
88 1.1 cgd "SIGILL", /* 4 illegal instruction (not reset when caught) */
89 1.1 cgd "SIGTRAP", /* 5 trace trap (not reset when caught) */
90 1.1 cgd "SIGIOT", /* 6 IOT instruction */
91 1.1 cgd "SIGEMT", /* 7 EMT instruction */
92 1.1 cgd "SIGFPE", /* 8 floating point exception */
93 1.1 cgd "SIGKILL", /* 9 kill (cannot be caught or ignored) */
94 1.1 cgd "SIGBUS", /* 10 bus error */
95 1.1 cgd "SIGSEGV", /* 11 segmentation violation */
96 1.1 cgd "SIGSYS", /* 12 bad argument to system call */
97 1.1 cgd "SIGPIPE", /* 13 write on a pipe with no one to read it */
98 1.1 cgd "SIGALRM", /* 14 alarm clock */
99 1.1 cgd "SIGTERM", /* 15 software termination signal from kill */
100 1.1 cgd "SIGURG", /* 16 urgent condition on IO channel */
101 1.1 cgd "SIGSTOP", /* 17 sendable stop signal not from tty */
102 1.1 cgd "SIGTSTP", /* 18 stop signal from tty */
103 1.1 cgd "SIGCONT", /* 19 continue a stopped process */
104 1.1 cgd "SIGCHLD", /* 20 to parent on child stop or exit */
105 1.1 cgd "SIGTTIN", /* 21 to readers pgrp upon background tty read */
106 1.1 cgd "SIGTTOU", /* 22 like TTIN for output if (tp->t_local<OSTOP) */
107 1.1 cgd "SIGIO", /* 23 input/output possible signal */
108 1.1 cgd "SIGXCPU", /* 24 exceeded CPU time limit */
109 1.1 cgd "SIGXFSZ", /* 25 exceeded file size limit */
110 1.1 cgd "SIGVTALRM",/* 26 virtual time alarm */
111 1.1 cgd "SIGPROF", /* 27 profiling time alarm */
112 1.1 cgd "","","","" };
113 1.1 cgd
114 1.1 cgd #else BSD /* for system V? */
115 1.1 cgd
116 1.1 cgd static char *signame[NSIG] = { "",
117 1.1 cgd "SIGHUP", /* 1 hangup */
118 1.1 cgd "SIGINT", /* 2 interrupt */
119 1.1 cgd "SIGQUIT", /* 3 quit */
120 1.1 cgd "SIGILL", /* 4 illegal instruction (not reset when caught) */
121 1.1 cgd "SIGTRAP", /* 5 trace trap (not reset when caught) */
122 1.1 cgd "SIGIOT", /* 6 IOT instruction */
123 1.1 cgd "SIGEMT", /* 7 EMT instruction */
124 1.1 cgd "SIGFPE", /* 8 floating point exception */
125 1.1 cgd "SIGKILL", /* 9 kill (cannot be caught or ignored) */
126 1.1 cgd "SIGBUS", /* 10 bus error */
127 1.1 cgd "SIGSEGV", /* 11 segmentation violation */
128 1.1 cgd "SIGSYS", /* 12 bad argument to system call */
129 1.1 cgd "SIGPIPE", /* 13 write on a pipe with no one to read it */
130 1.1 cgd "SIGALRM", /* 14 alarm clock */
131 1.1 cgd "SIGTERM", /* 15 software termination signal from kill */
132 1.1 cgd "SIGUSR1", /* 16 user defines signal 1 */
133 1.1 cgd "SIGUSR2", /* 17 user defines signal 2 */
134 1.1 cgd "SIGCLD", /* 18 child death */
135 1.1 cgd "SIGPWR", /* 19 power fail */
136 1.1 cgd "","","","","","","","","","","","" };
137 1.1 cgd
138 1.1 cgd #endif BSD
139 1.1 cgd
140 1.1 cgd /*
141 1.1 cgd * routine to process a fatal error signal
142 1.1 cgd */
143 1.1 cgd static void
144 1.1 cgd sigpanic(sig)
145 1.1 cgd int sig;
146 1.1 cgd {
147 1.1 cgd char buf[128];
148 1.1 cgd signal(sig,SIG_DFL);
149 1.1 cgd sprintf(buf,"\nLarn - Panic! Signal %d received [%s]",sig,signame[sig]);
150 1.1 cgd write(2,buf,strlen(buf)); sleep(2);
151 1.1 cgd sncbr();
152 1.1 cgd savegame(savefilename);
153 1.1 cgd kill(getpid(),sig); /* this will terminate us */
154 1.1 cgd }
155