Merge branch 'vendor/OPENSSL'
[dragonfly.git] / games / larn / signal.c
1 /* "Larn is copyrighted 1986 by Noah Morgan.\n" */
2
3 #include <signal.h>
4 #include "header.h"
5
6 static void s2choose(void);
7 static void cntlc(int);
8 static void sgam(int);
9 #ifdef SIGTSTP
10 static void tstop(int);
11 #endif
12 static void sigill(int);
13 static void sigtrap(int);
14 static void sigiot(int);
15 static void sigemt(int);
16 static void sigfpe(int);
17 static void sigbus(int);
18 static void sigsegv(int);
19 static void sigsys(int);
20 static void sigpipe(int);
21 static void sigterm(int);
22 static void sigpanic(int);
23
24 #define BIT(a) (1<<((a)-1))
25
26 static void
27 s2choose(void)  /* text to be displayed if ^C during intro screen */
28 {
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(__unused int sig) /* what to do for a ^C */
40 {
41         if (nosignal)   /* don't do anything if inhibited */
42                 return;
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(__unused int sig)
60 {
61         savegame(savefilename);
62         wizard = 1;
63         died(-257);             /* hangup signal */
64 }
65
66 #ifdef SIGTSTP
67 static void
68 tstop(__unused int sig) /* control Y */
69 {
70         if (nosignal)           /* nothing if inhibited */
71                 return;
72         lcreat(NULL);
73         clearvt100();
74         lflush();
75         signal(SIGTSTP, SIG_DFL);
76 #ifdef SIGVTALRM
77         /* looks like BSD4.2 or higher - must clr mask for signal to take effect*/
78         sigsetmask(sigblock(0) & ~BIT(SIGTSTP));
79 #endif
80         kill(getpid(), SIGTSTP);
81
82         setupvt100();
83         signal(SIGTSTP, tstop);
84         if (predostuff == 1)
85                 s2choose();
86         else
87                 drawscreen();
88         showplayer();
89         lflush();
90 }
91 #endif /* SIGTSTP */
92
93 /*
94  *      subroutine to issue the needed signal traps  called from main()
95  */
96 static void
97 sigill(__unused int sig)
98 {
99         sigpanic(SIGILL);
100 }
101
102 static void
103 sigtrap(__unused int sig)
104 {
105         sigpanic(SIGTRAP);
106 }
107
108 static void
109 sigiot(__unused int sig)
110 {
111         sigpanic(SIGIOT);
112 }
113
114 static void
115 sigemt(__unused int sig)
116 {
117         sigpanic(SIGEMT);
118 }
119
120 static void
121 sigfpe(__unused int sig)
122 {
123         sigpanic(SIGFPE);
124 }
125
126 static void
127 sigbus(__unused int sig)
128 {
129         sigpanic(SIGBUS);
130 }
131
132 static void
133 sigsegv(__unused int sig)
134 {
135         sigpanic(SIGSEGV);
136 }
137
138 static void
139 sigsys(__unused int sig)
140 {
141         sigpanic(SIGSYS);
142 }
143
144 static void
145 sigpipe(__unused int sig)
146 {
147         sigpanic(SIGPIPE);
148 }
149
150 static void
151 sigterm(__unused int sig)
152 {
153         sigpanic(SIGTERM);
154 }
155
156 void
157 sigsetup(void)
158 {
159         signal(SIGQUIT, cntlc);
160         signal(SIGINT, cntlc);
161         signal(SIGKILL, SIG_IGN);
162         signal(SIGHUP, sgam);
163         signal(SIGILL, sigill);
164         signal(SIGTRAP, sigtrap);
165         signal(SIGIOT, sigiot);
166         signal(SIGEMT, sigemt);
167         signal(SIGFPE, sigfpe);
168         signal(SIGBUS, sigbus);
169         signal(SIGSEGV, sigsegv);
170         signal(SIGSYS, sigsys);
171         signal(SIGPIPE, sigpipe);
172         signal(SIGTERM, sigterm);
173 #ifdef SIGTSTP
174         signal(SIGTSTP, tstop);
175         signal(SIGSTOP, tstop);
176 #endif /* SIGTSTP */
177 }
178
179 static const char *signame[NSIG] = { "",
180 "SIGHUP",  /*   1       hangup */
181 "SIGINT",  /*   2       interrupt */
182 "SIGQUIT", /*   3       quit */
183 "SIGILL",  /*   4       illegal instruction (not reset when caught) */
184 "SIGTRAP", /*   5       trace trap (not reset when caught) */
185 "SIGIOT",  /*   6       IOT instruction */
186 "SIGEMT",  /*   7       EMT instruction */
187 "SIGFPE",  /*   8       floating point exception */
188 "SIGKILL", /*   9       kill (cannot be caught or ignored) */
189 "SIGBUS",  /*  10       bus error */
190 "SIGSEGV", /*  11       segmentation violation */
191 "SIGSYS",  /*  12       bad argument to system call */
192 "SIGPIPE", /*  13       write on a pipe with no one to read it */
193 "SIGALRM", /*  14       alarm clock */
194 "SIGTERM", /*  15       software termination signal from kill */
195 "SIGURG",  /*  16       urgent condition on IO channel */
196 "SIGSTOP", /*  17       sendable stop signal not from tty */
197 "SIGTSTP", /*  18       stop signal from tty */
198 "SIGCONT", /*  19       continue a stopped process */
199 "SIGCHLD", /*  20       to parent on child stop or exit */
200 "SIGTTIN", /*  21       to readers pgrp upon background tty read */
201 "SIGTTOU", /*  22       like TTIN for output if (tp->t_local&LTOSTOP) */
202 "SIGIO",   /*  23       input/output possible signal */
203 "SIGXCPU", /*  24       exceeded CPU time limit */
204 "SIGXFSZ", /*  25       exceeded file size limit */
205 "SIGVTALRM",/* 26       virtual time alarm */
206 "SIGPROF", /*  27       profiling time alarm */
207 "SIGWINCH",/*  28       window size changes */
208 "SIGINFO", /*  29       information request */
209 "SIGUSR1", /*  30       user defined signal 1 */
210 "SIGUSR2", /*  31       user defined signal 2 */
211 };
212
213 /*
214  *      routine to process a fatal error signal
215  */
216 static void
217 sigpanic(int sig)
218 {
219         char buf[128];
220         signal(sig, SIG_DFL);
221         sprintf(buf, "\nLarn - Panic! Signal %d received [%s]", sig, signame[sig]);
222         write(2, buf, strlen(buf));
223         sleep(2);
224         sncbr();
225         savegame(savefilename);
226         kill(getpid(), sig);    /* this will terminate us */
227 }