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