NetBSD/games/warp/sig.c

224 lines
3.7 KiB
C

/* Header: /usr/src/games/warp/RCS/sig.c,v 1.1 87/07/03 01:47:11 games Exp */
/* Log: sig.c,v
* Revision 7.0.1.1a 87/07/03 01:47:11 games
* Changed sigsetmask to use sigmask instead of calculating it (incorrectly)
* by hand.
*
* Revision 7.0.1.1 86/12/12 17:02:44 lwall
* Baseline for net release.
*
* Revision 7.0 86/10/08 15:13:24 lwall
* Split into separate files. Added amoebas and pirates.
*
*/
#include "EXTERN.h"
#include "warp.h"
#include "play.h"
#include "score.h"
#include "term.h"
#include "util.h"
#include "INTERN.h"
#include "sig.h"
void
sig_init(void)
{
sigignore(SIGINT); /* for inquiry of existence via kill call */
#ifdef SIGTTOU
sigignore(SIGTTOU);
#endif
sigset(SIGHUP, sig_catcher);
if (!debugging) {
sigset(SIGQUIT, sig_catcher);
sigset(SIGILL, sig_catcher);
sigset(SIGFPE, sig_catcher);
#if 0
sigset(SIGBUS, sig_catcher);
sigset(SIGSEGV, sig_catcher);
#endif
sigset(SIGSYS, sig_catcher);
sigset(SIGTERM, sig_catcher);
}
#ifdef SIGXCPU
sigset(SIGXCPU, sig_catcher);
#endif
#ifdef SIGCONT
sigset(SIGCONT, cont_catcher);
#endif
#ifdef SIGTSTP
sigset(SIGTSTP, stop_catcher);
sigset(SIGSTOP, stop_catcher);
#endif
}
#ifdef SIGTSTP
void
cont_catcher(int x)
{
#ifndef lint
sigset(SIGCONT,cont_catcher);
#endif
savetty();
crmode();
raw();
noecho();
nonl();
}
#endif
void
mytstp(void)
{
resetty();
#ifdef SIGTSTP
kill(0,SIGTSTP);
#else
if (fork())
wait(0);
else {
char *shell = getenv("SHELL");
setuid(getuid());
if (!*shell)
shell = "/bin/sh";
execl(shell,shell,0);
exit(1);
}
#endif
rewrite();
}
void /* very much void */
finalize(int status)
{
if (bizarre)
resetty();
if (status < 0) {
chdir("/usr/tmp");
sigset(SIGILL,SIG_DFL);
abort();
}
exit(status);
}
/* come here on signal other than interrupt, stop, or cont */
void
sig_catcher(int signo)
{
#ifdef VERBOSE
static const char *signame[] = {
"",
"HUP",
"INT",
"QUIT",
"ILL",
"TRAP",
"IOT",
"EMT",
"FPE",
"KILL",
"BUS",
"SEGV",
"SYS",
"PIPE",
"ALRM",
"TERM",
"???"
#ifdef SIGTSTP
,"STOP",
"TSTP",
"CONT",
"CHLD",
"TTIN",
"TTOU",
"TINT",
"XCPU",
"XFSZ"
#ifdef SIGPROF
,"VTALARM",
"PROF"
#endif
#endif
};
#endif
#ifdef SIGTTOU
#ifndef lint
sigignore(SIGTTOU);
#endif /* lint */
#endif
#ifdef DEBUGGING
if (debug) {
printf("\r\nSIG%s--game not saved in debug\r\n",signame[signo]);
finalize(-1);
}
#endif
panic++;
if (panic >= 2) {
if (panic >= 3)
abort();
chdir(SAVEDIR);
kill(0,SIGIOT);
}
(void) sigset(SIGILL,SIG_DFL);
if (signo == SIGHUP && (timer < 10 || didkill))
signo = SIGQUIT;
if (signo == SIGQUIT) { /* can't let them bomb out without penalty */
if (smarts < 20)
smarts += 4;
else if (smarts < 35)
smarts += 2;
else
smarts++;
totalscore -= possiblescore / 2;
}
save_game();
if (signo != SIGHUP && signo != SIGQUIT) {
#ifdef VERBOSE
IF(verbose)
printf("\r\nCaught %s%s--%s\r\n",
signo ? "a SIG" : "an internal error", signame[signo],
experimenting ? "game saved" : "bye bye");
ELSE
#endif
#ifdef TERSE
printf("\r\nsignal %d--bye bye\r\n",signo);
#endif
}
switch (signo) {
case SIGBUS:
case SIGILL:
case SIGSEGV:
finalize(-signo);
}
finalize(1); /* and blow up */
}
#ifdef SIGTSTP
/* come here on stop signal */
void
stop_catcher(int sig)
{
if (!waiting) {
resetty(); /* this is the point of all this */
#ifdef DEBUGGING
if (debug)
write(2,"stop_catcher\r\n",13);
#endif
sigset(SIGTSTP,SIG_DFL); /* enable stop */
#ifdef BSD42
sigsetmask(sigblock(0L) & ~sigmask(SIGTSTP));
#endif
kill(0,SIGTSTP); /* and do the stop */
}
#ifndef lint
sigset(SIGTSTP,stop_catcher); /* unenable the stop */
#endif
}
#endif