xref: /netbsd/games/larn/signal.c (revision bf9ec67e)
1 /*	$NetBSD: signal.c,v 1.7 2001/02/05 00:57:34 christos 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.7 2001/02/05 00:57:34 christos 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 __P((void));
18 static void cntlc __P((int));
19 static void sgam __P((int));
20 static void tstop __P((int));
21 static void sigpanic __P((int));
22 
23 #define BIT(a) (1<<((a)-1))
24 
25 static void
26 s2choose()
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(n)
40 	int n;
41 {				/* what to do for a ^C */
42 	if (nosignal)
43 		return;		/* don't do anything if inhibited */
44 	signal(SIGQUIT, SIG_IGN);
45 	signal(SIGINT, SIG_IGN);
46 	quit();
47 	if (predostuff == 1)
48 		s2choose();
49 	else
50 		showplayer();
51 	lflush();
52 	signal(SIGQUIT, cntlc);
53 	signal(SIGINT, cntlc);
54 }
55 
56 /*
57  *	subroutine to save the game if a hangup signal
58  */
59 static void
60 sgam(n)
61 	int n;
62 {
63 	savegame(savefilename);
64 	wizard = 1;
65 	died(-257);		/* hangup signal */
66 }
67 
68 #ifdef SIGTSTP
69 static void
70 tstop(n)
71 	int n;
72 {				/* control Y	 */
73 	if (nosignal)
74 		return;		/* nothing if inhibited */
75 	lcreat((char *) 0);
76 	clearvt100();
77 	lflush();
78 	signal(SIGTSTP, SIG_DFL);
79 #ifdef SIGVTALRM
80 	/*
81 	 * looks like BSD4.2 or higher - must clr mask for signal to take
82 	 * effect
83 	 */
84 	sigsetmask(sigblock(0) & ~BIT(SIGTSTP));
85 #endif
86 	kill(getpid(), SIGTSTP);
87 
88 	setupvt100();
89 	signal(SIGTSTP, tstop);
90 	if (predostuff == 1)
91 		s2choose();
92 	else
93 		drawscreen();
94 	showplayer();
95 	lflush();
96 }
97 #endif	/* SIGTSTP */
98 
99 /*
100  *	subroutine to issue the needed signal traps  called from main()
101  */
102 void
103 sigsetup()
104 {
105 	signal(SIGQUIT, cntlc);
106 	signal(SIGINT, cntlc);
107 	signal(SIGKILL, SIG_IGN);
108 	signal(SIGHUP, sgam);
109 	signal(SIGILL, sigpanic);
110 	signal(SIGTRAP, sigpanic);
111 	signal(SIGIOT, sigpanic);
112 	signal(SIGEMT, sigpanic);
113 	signal(SIGFPE, sigpanic);
114 	signal(SIGBUS, sigpanic);
115 	signal(SIGSEGV, sigpanic);
116 	signal(SIGSYS, sigpanic);
117 	signal(SIGPIPE, sigpanic);
118 	signal(SIGTERM, sigpanic);
119 #ifdef SIGTSTP
120 	signal(SIGTSTP, tstop);
121 	signal(SIGSTOP, tstop);
122 #endif	/* SIGTSTP */
123 }
124 
125 /*
126  *	routine to process a fatal error signal
127  */
128 static void
129 sigpanic(sig)
130 	int             sig;
131 {
132 	char            buf[128];
133 	signal(sig, SIG_DFL);
134 	snprintf(buf, sizeof(buf),
135 	    "\nLarn - Panic! Signal %d received [SIG%s]", sig,
136 	    sys_signame[sig]);
137 	write(2, buf, strlen(buf));
138 	sleep(2);
139 	sncbr();
140 	savegame(savefilename);
141 	kill(getpid(), sig);	/* this will terminate us */
142 }
143