signal.c revision 1.8
1/*	$NetBSD: signal.c,v 1.8 2004/01/27 20:30:30 jsm 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.8 2004/01/27 20:30:30 jsm 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
17static void s2choose(void);
18static void cntlc(int);
19static void sgam(int);
20static void tstop(int);
21static void sigpanic(int);
22
23#define BIT(a) (1<<((a)-1))
24
25static void
26s2choose()
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
38static void
39cntlc(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 */
59static void
60sgam(n)
61	int n;
62{
63	savegame(savefilename);
64	wizard = 1;
65	died(-257);		/* hangup signal */
66}
67
68#ifdef SIGTSTP
69static void
70tstop(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 */
102void
103sigsetup()
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 */
128static void
129sigpanic(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