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