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