1/* Header: /usr/src/games/warp/RCS/sig.c,v 1.1 87/07/03 01:47:11 games Exp */
2
3/* Log:	sig.c,v
4 * Revision 7.0.1.1a  87/07/03  01:47:11  games
5 * Changed sigsetmask to use sigmask instead of calculating it (incorrectly)
6 * by hand.
7 *
8 * Revision 7.0.1.1  86/12/12  17:02:44  lwall
9 * Baseline for net release.
10 *
11 * Revision 7.0  86/10/08  15:13:24  lwall
12 * Split into separate files.  Added amoebas and pirates.
13 *
14 */
15
16#include "EXTERN.h"
17#include "warp.h"
18#include "play.h"
19#include "score.h"
20#include "term.h"
21#include "util.h"
22#include "INTERN.h"
23#include "sig.h"
24
25void
26sig_init(void)
27{
28    sigignore(SIGINT);  /* for inquiry of existence via kill call */
29#ifdef SIGTTOU
30    sigignore(SIGTTOU);
31#endif
32
33    sigset(SIGHUP, sig_catcher);
34    if (!debugging) {
35	sigset(SIGQUIT, sig_catcher);
36	sigset(SIGILL, sig_catcher);
37	sigset(SIGFPE, sig_catcher);
38#if 0
39	sigset(SIGBUS, sig_catcher);
40	sigset(SIGSEGV, sig_catcher);
41#endif
42	sigset(SIGSYS, sig_catcher);
43	sigset(SIGTERM, sig_catcher);
44    }
45#ifdef SIGXCPU
46    sigset(SIGXCPU, sig_catcher);
47#endif
48#ifdef SIGCONT
49    sigset(SIGCONT, cont_catcher);
50#endif
51#ifdef SIGTSTP
52    sigset(SIGTSTP, stop_catcher);
53    sigset(SIGSTOP, stop_catcher);
54#endif
55}
56
57#ifdef SIGTSTP
58void
59cont_catcher(int x)
60{
61#ifndef lint
62    sigset(SIGCONT,cont_catcher);
63#endif
64    savetty();
65    crmode();
66    raw();
67    noecho();
68    nonl();
69}
70#endif
71
72void
73mytstp(void)
74{
75    resetty();
76#ifdef SIGTSTP
77    kill(0,SIGTSTP);
78#else
79    if (fork())
80	wait(0);
81    else {
82	char *shell = getenv("SHELL");
83
84	setuid(getuid());
85	if (!*shell)
86	    shell = "/bin/sh";
87	execl(shell,shell,0);
88	exit(1);
89    }
90#endif
91    rewrite();
92}
93
94void					/* very much void */
95finalize(int status)
96{
97    if (bizarre)
98	resetty();
99    if (status < 0) {
100	chdir("/usr/tmp");
101	sigset(SIGILL,SIG_DFL);
102	abort();
103    }
104    exit(status);
105}
106
107/* come here on signal other than interrupt, stop, or cont */
108
109void
110sig_catcher(int signo)
111{
112#ifdef VERBOSE
113    static const char *signame[] = {
114	"",
115	"HUP",
116	"INT",
117	"QUIT",
118	"ILL",
119	"TRAP",
120	"IOT",
121	"EMT",
122	"FPE",
123	"KILL",
124	"BUS",
125	"SEGV",
126	"SYS",
127	"PIPE",
128	"ALRM",
129	"TERM",
130	"???"
131#ifdef SIGTSTP
132	,"STOP",
133	"TSTP",
134	"CONT",
135	"CHLD",
136	"TTIN",
137	"TTOU",
138	"TINT",
139	"XCPU",
140	"XFSZ"
141#ifdef SIGPROF
142	,"VTALARM",
143	"PROF"
144#endif
145#endif
146	};
147#endif
148
149#ifdef SIGTTOU
150#ifndef lint
151    sigignore(SIGTTOU);
152#endif /* lint */
153#endif
154#ifdef DEBUGGING
155    if (debug) {
156	printf("\r\nSIG%s--game not saved in debug\r\n",signame[signo]);
157	finalize(-1);
158    }
159#endif
160    panic++;
161    if (panic >= 2) {
162	if (panic >= 3)
163	    abort();
164	chdir(SAVEDIR);
165	kill(0,SIGIOT);
166    }
167    (void) sigset(SIGILL,SIG_DFL);
168    if (signo == SIGHUP && (timer < 10 || didkill))
169	signo = SIGQUIT;
170    if (signo == SIGQUIT) {	/* can't let them bomb out without penalty */
171	if (smarts < 20)
172	    smarts += 4;
173	else if (smarts < 35)
174	    smarts += 2;
175	else
176	    smarts++;
177	totalscore -= possiblescore / 2;
178    }
179    save_game();
180    if (signo != SIGHUP && signo != SIGQUIT) {
181#ifdef VERBOSE
182	IF(verbose)
183	    printf("\r\nCaught %s%s--%s\r\n",
184		signo ? "a SIG" : "an internal error", signame[signo],
185		experimenting ? "game saved" : "bye bye");
186	ELSE
187#endif
188#ifdef TERSE
189	    printf("\r\nsignal %d--bye bye\r\n",signo);
190#endif
191    }
192    switch (signo) {
193    case SIGBUS:
194    case SIGILL:
195    case SIGSEGV:
196	finalize(-signo);
197    }
198    finalize(1);				/* and blow up */
199}
200
201#ifdef SIGTSTP
202/* come here on stop signal */
203
204void
205stop_catcher(int sig)
206{
207    if (!waiting) {
208	resetty();			/* this is the point of all this */
209#ifdef DEBUGGING
210	if (debug)
211	    write(2,"stop_catcher\r\n",13);
212#endif
213	sigset(SIGTSTP,SIG_DFL);	/* enable stop */
214#ifdef BSD42
215	sigsetmask(sigblock(0L) & ~sigmask(SIGTSTP));
216#endif
217	kill(0,SIGTSTP);		/* and do the stop */
218    }
219#ifndef lint
220    sigset(SIGTSTP,stop_catcher);	/* unenable the stop */
221#endif
222}
223#endif
224