136999Sbostic #include <signal.h>
236999Sbostic #include "header.h" /* "Larn is copyrighted 1986 by Noah Morgan.\n" */
336999Sbostic #define BIT(a) (1<<((a)-1))
436999Sbostic extern char savefilename[],wizard,predostuff,nosignal;
s2choose()536999Sbostic static s2choose() /* text to be displayed if ^C during intro screen */
636999Sbostic {
736999Sbostic cursor(1,24); lprcat("Press "); setbold(); lprcat("return"); resetbold();
836999Sbostic lprcat(" to continue: "); lflush();
936999Sbostic }
1036999Sbostic
11*46749Sbostic static void
cntlc()12*46749Sbostic cntlc() /* what to do for a ^C */
1336999Sbostic {
1436999Sbostic if (nosignal) return; /* don't do anything if inhibited */
1536999Sbostic signal(SIGQUIT,SIG_IGN); signal(SIGINT,SIG_IGN);
1636999Sbostic quit(); if (predostuff==1) s2choose(); else showplayer();
1736999Sbostic lflush();
1836999Sbostic signal(SIGQUIT,cntlc); signal(SIGINT,cntlc);
1936999Sbostic }
2036999Sbostic
2136999Sbostic /*
2236999Sbostic * subroutine to save the game if a hangup signal
2336999Sbostic */
24*46749Sbostic static void
sgam()25*46749Sbostic sgam()
2636999Sbostic {
2736999Sbostic savegame(savefilename); wizard=1; died(-257); /* hangup signal */
2836999Sbostic }
2936999Sbostic
3036999Sbostic #ifdef SIGTSTP
31*46749Sbostic static void
tstop()32*46749Sbostic tstop() /* control Y */
3336999Sbostic {
3436999Sbostic if (nosignal) return; /* nothing if inhibited */
3536999Sbostic lcreat((char*)0); clearvt100(); lflush(); signal(SIGTSTP,SIG_DFL);
3636999Sbostic #ifdef SIGVTALRM
3736999Sbostic /* looks like BSD4.2 or higher - must clr mask for signal to take effect*/
3836999Sbostic sigsetmask(sigblock(0)& ~BIT(SIGTSTP));
3936999Sbostic #endif
4036999Sbostic kill(getpid(),SIGTSTP);
4136999Sbostic
4236999Sbostic setupvt100(); signal(SIGTSTP,tstop);
4336999Sbostic if (predostuff==1) s2choose(); else drawscreen();
4436999Sbostic showplayer(); lflush();
4536999Sbostic }
4636999Sbostic #endif SIGTSTP
4736999Sbostic
4836999Sbostic /*
4936999Sbostic * subroutine to issue the needed signal traps called from main()
5036999Sbostic */
51*46749Sbostic static void sigpanic();
sigill()52*46749Sbostic static void sigill() { sigpanic(SIGILL); }
sigtrap()53*46749Sbostic static void sigtrap() { sigpanic(SIGTRAP); }
sigiot()54*46749Sbostic static void sigiot() { sigpanic(SIGIOT); }
sigemt()55*46749Sbostic static void sigemt() { sigpanic(SIGEMT); }
sigfpe()56*46749Sbostic static void sigfpe() { sigpanic(SIGFPE); }
sigbus()57*46749Sbostic static void sigbus() { sigpanic(SIGBUS); }
sigsegv()58*46749Sbostic static void sigsegv() { sigpanic(SIGSEGV); }
sigsys()59*46749Sbostic static void sigsys() { sigpanic(SIGSYS); }
sigpipe()60*46749Sbostic static void sigpipe() { sigpanic(SIGPIPE); }
sigterm()61*46749Sbostic static void sigterm() { sigpanic(SIGTERM); }
sigsetup()6236999Sbostic sigsetup()
6336999Sbostic {
6436999Sbostic signal(SIGQUIT, cntlc); signal(SIGINT, cntlc);
6536999Sbostic signal(SIGKILL, SIG_IGN); signal(SIGHUP, sgam);
6636999Sbostic signal(SIGILL, sigill); signal(SIGTRAP, sigtrap);
6736999Sbostic signal(SIGIOT, sigiot); signal(SIGEMT, sigemt);
6836999Sbostic signal(SIGFPE, sigfpe); signal(SIGBUS, sigbus);
6936999Sbostic signal(SIGSEGV, sigsegv); signal(SIGSYS, sigsys);
7036999Sbostic signal(SIGPIPE, sigpipe); signal(SIGTERM, sigterm);
7136999Sbostic #ifdef SIGTSTP
7236999Sbostic signal(SIGTSTP,tstop); signal(SIGSTOP,tstop);
7336999Sbostic #endif SIGTSTP
7436999Sbostic }
7536999Sbostic
7636999Sbostic #ifdef BSD /* for BSD UNIX? */
7736999Sbostic
7836999Sbostic static char *signame[NSIG] = { "",
7936999Sbostic "SIGHUP", /* 1 hangup */
8036999Sbostic "SIGINT", /* 2 interrupt */
8136999Sbostic "SIGQUIT", /* 3 quit */
8236999Sbostic "SIGILL", /* 4 illegal instruction (not reset when caught) */
8336999Sbostic "SIGTRAP", /* 5 trace trap (not reset when caught) */
8436999Sbostic "SIGIOT", /* 6 IOT instruction */
8536999Sbostic "SIGEMT", /* 7 EMT instruction */
8636999Sbostic "SIGFPE", /* 8 floating point exception */
8736999Sbostic "SIGKILL", /* 9 kill (cannot be caught or ignored) */
8836999Sbostic "SIGBUS", /* 10 bus error */
8936999Sbostic "SIGSEGV", /* 11 segmentation violation */
9036999Sbostic "SIGSYS", /* 12 bad argument to system call */
9136999Sbostic "SIGPIPE", /* 13 write on a pipe with no one to read it */
9236999Sbostic "SIGALRM", /* 14 alarm clock */
9336999Sbostic "SIGTERM", /* 15 software termination signal from kill */
9436999Sbostic "SIGURG", /* 16 urgent condition on IO channel */
9536999Sbostic "SIGSTOP", /* 17 sendable stop signal not from tty */
9636999Sbostic "SIGTSTP", /* 18 stop signal from tty */
9736999Sbostic "SIGCONT", /* 19 continue a stopped process */
9836999Sbostic "SIGCHLD", /* 20 to parent on child stop or exit */
9936999Sbostic "SIGTTIN", /* 21 to readers pgrp upon background tty read */
10036999Sbostic "SIGTTOU", /* 22 like TTIN for output if (tp->t_local<OSTOP) */
10136999Sbostic "SIGIO", /* 23 input/output possible signal */
10236999Sbostic "SIGXCPU", /* 24 exceeded CPU time limit */
10336999Sbostic "SIGXFSZ", /* 25 exceeded file size limit */
10436999Sbostic "SIGVTALRM",/* 26 virtual time alarm */
10536999Sbostic "SIGPROF", /* 27 profiling time alarm */
10636999Sbostic "","","","" };
10736999Sbostic
10836999Sbostic #else BSD /* for system V? */
10936999Sbostic
11036999Sbostic static char *signame[NSIG] = { "",
11136999Sbostic "SIGHUP", /* 1 hangup */
11236999Sbostic "SIGINT", /* 2 interrupt */
11336999Sbostic "SIGQUIT", /* 3 quit */
11436999Sbostic "SIGILL", /* 4 illegal instruction (not reset when caught) */
11536999Sbostic "SIGTRAP", /* 5 trace trap (not reset when caught) */
11636999Sbostic "SIGIOT", /* 6 IOT instruction */
11736999Sbostic "SIGEMT", /* 7 EMT instruction */
11836999Sbostic "SIGFPE", /* 8 floating point exception */
11936999Sbostic "SIGKILL", /* 9 kill (cannot be caught or ignored) */
12036999Sbostic "SIGBUS", /* 10 bus error */
12136999Sbostic "SIGSEGV", /* 11 segmentation violation */
12236999Sbostic "SIGSYS", /* 12 bad argument to system call */
12336999Sbostic "SIGPIPE", /* 13 write on a pipe with no one to read it */
12436999Sbostic "SIGALRM", /* 14 alarm clock */
12536999Sbostic "SIGTERM", /* 15 software termination signal from kill */
12636999Sbostic "SIGUSR1", /* 16 user defines signal 1 */
12736999Sbostic "SIGUSR2", /* 17 user defines signal 2 */
12836999Sbostic "SIGCLD", /* 18 child death */
12936999Sbostic "SIGPWR", /* 19 power fail */
13036999Sbostic "","","","","","","","","","","","" };
13136999Sbostic
13236999Sbostic #endif BSD
13336999Sbostic
13436999Sbostic /*
13536999Sbostic * routine to process a fatal error signal
13636999Sbostic */
137*46749Sbostic static void
sigpanic(sig)138*46749Sbostic sigpanic(sig)
13936999Sbostic int sig;
14036999Sbostic {
14136999Sbostic char buf[128];
14236999Sbostic signal(sig,SIG_DFL);
14336999Sbostic sprintf(buf,"\nLarn - Panic! Signal %d received [%s]",sig,signame[sig]);
14436999Sbostic write(2,buf,strlen(buf)); sleep(2);
14536999Sbostic sncbr();
14636999Sbostic savegame(savefilename);
14736999Sbostic kill(getpid(),sig); /* this will terminate us */
14836999Sbostic }
149