1 /* source/signals.c: signal handlers
2
3 Copyright (c) 1989-94 James E. Wilson, Christopher J. Stuart
4
5 This software may be copied and distributed for educational, research, and
6 not for profit purposes provided that this copyright and statement are
7 included in all such copies. */
8
9 /* This signal package was brought to you by -JEW- */
10 /* Completely rewritten by -CJS- */
11
12 /* To find out what system we're on. */
13
14 #include <stdio.h>
15
16 #include "config.h"
17 #include "constant.h"
18
19 /* Signals have no significance on the Mac */
20
21 #ifdef MAC
22
nosignals()23 void nosignals()
24 {
25 }
26
signals()27 void signals()
28 {
29 }
30
init_signals()31 void init_signals()
32 {
33 }
34
35 #else /* a non-Mac system */
36
37 #ifdef ATARIST_MWC
38 /* need these for atari st, but for unix, must include signals.h first,
39 or else suspend won't be properly declared */
40 #include "types.h"
41 #include "externs.h"
42 #endif
43
44 /* skip most of the file on an ATARI ST */
45 /* commented away most single handling for Atari ST TC too, as this
46 doesn't work as it should. */
47 #if !defined(ATARIST_MWC) && !defined(ATARIST_TC)
48
49 #if defined(SYS_V) && defined(lint)
50 /* for AIX, prevent hundreds of unnecessary lint errors, define before
51 signal.h is included */
52 #define _h_IEEETRAP
53 typedef struct { int stuff; } fpvmach;
54 #endif
55
56 /* must include before externs.h, because that uses SIGTSTP */
57 #include <signal.h>
58
59 #include "types.h"
60 #include "externs.h"
61
62 #ifndef USG
63 /* only needed for Berkeley UNIX */
64 #include <sys/types.h>
65 #include <sys/param.h>
66 #endif
67
68 #ifdef USG
69 #ifndef ATARIST_MWC
70 #include <string.h>
71 #endif
72 #else
73 #include <strings.h>
74 #endif
75
76 #ifndef VMS
77 #ifdef USG
78 void exit();
79 #ifdef __TURBOC__
80 void sleep();
81 #else
82 unsigned sleep();
83 #endif
84 #endif
85 #endif
86
87 static int error_sig = -1;
88 static int signal_count = 0;
89
90 /*ARGSUSED*/
91 #ifndef USG
92 #if defined(__386BSD__) || defined(__FreeBSD__)
signal_handler(sig,code,scp)93 static void signal_handler(sig, code, scp)
94 #else
95 static int signal_handler(sig, code, scp)
96 #endif
97 int sig, code;
98 struct sigcontext *scp;
99 {
100 int smask;
101
102 smask = sigsetmask(0) | (1 << sig);
103 #else
104 #if defined(__TURBOC__) || defined(AMIGA)
105 static void signal_handler(sig)
106 #else
107 static int signal_handler(sig)
108 #endif
109 int sig;
110 {
111 #endif
112
113 if(error_sig >= 0) /* Ignore all second signals. */
114 {
115 if(++signal_count > 10) /* Be safe. We will die if persistent enough. */
116 (void) signal(sig, SIG_DFL);
117 return;
118 }
119 error_sig = sig;
120
121 /* Allow player to think twice. Wizard may force a core dump. */
122 if (sig == SIGINT
123 #if !defined(MSDOS) && !defined(AMIGA) && !defined(ATARIST_TC)
124 || sig == SIGQUIT
125 #endif
126 )
127 {
128 if (death)
129 (void) signal(sig, SIG_IGN); /* Can't quit after death. */
130 else if (!character_saved && character_generated)
131 {
132 if (!get_check("Really commit *Suicide*?"))
133 {
134 if (turn > 0)
135 disturb(1, 0);
136 erase_line(0, 0);
137 put_qio();
138 error_sig = -1;
139 #ifdef USG
140 (void) signal(sig, signal_handler);/* Have to restore handler. */
141 #else
142 (void) sigsetmask(smask);
143 #endif
144 /* in case control-c typed during msg_print */
145 if (wait_for_more)
146 put_buffer(" -more-", MSG_LINE, 0);
147 put_qio();
148 return; /* OK. We don't quit. */
149 }
150 (void) strcpy(died_from, "Interrupting");
151 }
152 else
153 (void) strcpy(died_from, "Abortion");
154 prt("Interrupt!", 0, 0);
155 death = TRUE;
156 exit_game();
157 }
158 /* Die. */
159 prt(
160 "OH NO!!!!!! A gruesome software bug LEAPS out at you. There is NO defense!",
161 23, 0);
162 if (!death && !character_saved && character_generated)
163 {
164 panic_save = 1;
165 prt("Your guardian angel is trying to save you.", 0, 0);
166 (void) sprintf(died_from,"(panic save %d)",sig);
167 if (!save_char())
168 {
169 (void) strcpy(died_from, "software bug");
170 death = TRUE;
171 turn = -1;
172 }
173 }
174 else
175 {
176 death = TRUE;
177 (void) _save_char(savefile); /* Quietly save the memory anyway. */
178 }
179 restore_term();
180 #if !defined(MSDOS) && !defined(AMIGA) && !defined(ATARIST_TC)
181 /* always generate a core dump */
182 (void) signal(sig, SIG_DFL);
183 (void) kill(getpid(), sig);
184 (void) sleep(5);
185 #endif
186 exit(1);
187 }
188
189 #endif /* ATARIST_MWC, ATARIST_TC */
190
191 #ifndef USG
192 static int mask;
193 #endif
194
nosignals()195 void nosignals()
196 {
197 #if !defined(ATARIST_MWC) && !defined(ATARIST_TC)
198 #ifdef SIGTSTP
199 #if defined(atarist) && defined(__GNUC__)
200 (void) signal(SIGTSTP, (__Sigfunc)SIG_IGN);
201 #else
202 (void) signal(SIGTSTP, SIG_IGN);
203 #endif
204 #ifndef USG
205 mask = sigsetmask(0);
206 #endif
207 #endif
208 if (error_sig < 0)
209 error_sig = 0;
210 #endif
211 }
212
signals()213 void signals()
214 {
215 #if !defined(ATARIST_MWC) && !defined(ATARIST_TC)
216 #ifdef SIGTSTP
217 #if defined(atarist) && defined(__GNUC__)
218 (void) signal(SIGTSTP, (__Sigfunc)suspend);
219 #else
220 #if defined(__386BSD__) || defined(__FreeBSD__)
221 (void) signal(SIGTSTP, (sig_t)suspend);
222 #else
223 (void) signal(SIGTSTP, suspend);
224 #endif
225 #endif
226 #ifndef USG
227 (void) sigsetmask(mask);
228 #endif
229 #endif
230 if (error_sig == 0)
231 error_sig = -1;
232 #endif
233 }
234
235
init_signals()236 void init_signals()
237 {
238 #if !defined(ATARIST_MWC) && !defined(ATARIST_TC)
239 /* No signals for Atari ST compiled with MWC or TC. */
240 (void) signal(SIGINT, signal_handler);
241
242 #if defined(atarist) && defined(__GNUC__)
243 /* Atari ST compiled with GNUC has most signals, but we need a cast
244 in every call to signal. */
245 (void) signal(SIGINT, (__Sigfunc)signal_handler);
246 (void) signal(SIGQUIT, (__Sigfunc)signal_handler);
247 (void) signal(SIGTSTP,(__Sigfunc)SIG_IGN);
248 (void) signal(SIGILL, (__Sigfunc)signal_handler);
249 (void) signal(SIGHUP, (__Sigfunc)SIG_IGN);
250 (void) signal(SIGTRAP,(__Sigfunc)signal_handler);
251 (void) signal(SIGIOT, (__Sigfunc)signal_handler);
252 (void) signal(SIGEMT, (__Sigfunc)signal_handler);
253 (void) signal(SIGKILL, (__Sigfunc)signal_handler);
254 (void) signal(SIGBUS, (__Sigfunc)signal_handler);
255 (void) signal(SIGSEGV, (__Sigfunc)signal_handler);
256 (void) signal(SIGSYS, (__Sigfunc)signal_handler);
257 (void) signal(SIGTERM,(__Sigfunc)signal_handler);
258 (void) signal(SIGPIPE, (__Sigfunc)signal_handler);
259
260 #else
261 /* Everybody except the atari st. */
262 (void) signal(SIGINT, signal_handler);
263 (void) signal(SIGFPE, signal_handler);
264
265 #if defined(MSDOS)
266 /* many fewer signals under MSDOS */
267 #else
268
269 #ifdef AMIGA
270 /* (void) signal(SIGINT, signal_handler); */
271 (void) signal(SIGTERM, signal_handler);
272 (void) signal(SIGABRT, signal_handler);
273 /* (void) signal(SIGFPE, signal_handler); */
274 (void) signal(SIGILL, signal_handler);
275 (void) signal(SIGSEGV, signal_handler);
276
277 #else
278
279 /* Everybody except Atari, MSDOS, and Amiga. */
280 /* Ignore HANGUP, and let the EOF code take care of this case. */
281 (void) signal(SIGHUP, SIG_IGN);
282 (void) signal(SIGQUIT, signal_handler);
283 (void) signal(SIGILL, signal_handler);
284 (void) signal(SIGTRAP, signal_handler);
285 (void) signal(SIGIOT, signal_handler);
286 #ifdef SIGEMT /* in BSD systems */
287 (void) signal(SIGEMT, signal_handler);
288 #endif
289 #ifdef SIGDANGER /* in SYSV systems */
290 (void) signal(SIGDANGER, signal_handler);
291 #endif
292 (void) signal(SIGKILL, signal_handler);
293 (void) signal(SIGBUS, signal_handler);
294 (void) signal(SIGSEGV, signal_handler);
295 #ifdef SIGSYS
296 (void) signal(SIGSYS, signal_handler);
297 #endif
298 (void) signal(SIGTERM, signal_handler);
299 (void) signal(SIGPIPE, signal_handler);
300 #ifdef SIGXCPU /* BSD */
301 (void) signal(SIGXCPU, signal_handler);
302 #endif
303 #ifdef SIGPWR /* SYSV */
304 (void) signal(SIGPWR, signal_handler);
305 #endif
306 #endif
307 #endif
308 #endif
309 #endif
310 }
311
ignore_signals()312 void ignore_signals()
313 {
314 #if !defined(ATARIST_MWC)
315 (void) signal(SIGINT, SIG_IGN);
316 #ifdef SIGQUIT
317 (void) signal(SIGQUIT, SIG_IGN);
318 #endif
319 #endif
320 }
321
default_signals()322 void default_signals()
323 {
324 #if !defined(ATARIST_MWC)
325 (void) signal(SIGINT, SIG_DFL);
326 #ifdef SIGQUIT
327 (void) signal(SIGQUIT, SIG_DFL);
328 #endif
329 #endif
330 }
331
restore_signals()332 void restore_signals()
333 {
334 #if !defined(ATARIST_MWC)
335 #if defined(atarist) && defined(__GNUC__)
336 (void) signal(SIGINT, (__Sigfunc)signal_handler);
337 #else
338 (void) signal(SIGINT, signal_handler);
339 #endif
340 #ifdef SIGQUIT
341 #if defined(atarist) && defined(__GNUC__)
342 (void) signal(SIGQUIT, (__Sigfunc)signal_handler);
343 #else
344 (void) signal(SIGQUIT, signal_handler);
345 #endif
346 #endif
347 #endif
348 }
349
350 #endif /* big Mac conditional */
351