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(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
38static void
39cntlc(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 */
58static void
59sgam(int n)
60{
61	savegame(savefilename);
62	wizard = 1;
63	died(-257);		/* hangup signal */
64}
65
66#ifdef SIGTSTP
67static void
68tstop(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 */
99void
100sigsetup(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 */
125static void
126sigpanic(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