xref: /csrg-svn/games/larn/signal.c (revision 46749)
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&LTOSTOP) */
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