xref: /csrg-svn/games/larn/signal.c (revision 36999)
1*36999Sbostic #include <signal.h>
2*36999Sbostic #include "header.h"			/* "Larn is copyrighted 1986 by Noah Morgan.\n" */
3*36999Sbostic #define BIT(a) (1<<((a)-1))
4*36999Sbostic extern char savefilename[],wizard,predostuff,nosignal;
5*36999Sbostic static s2choose()	/* text to be displayed if ^C during intro screen */
6*36999Sbostic 	{
7*36999Sbostic 	cursor(1,24); lprcat("Press "); setbold(); lprcat("return"); resetbold();
8*36999Sbostic 	lprcat(" to continue: ");   lflush();
9*36999Sbostic 	}
10*36999Sbostic 
11*36999Sbostic static cntlc()	/* what to do for a ^C */
12*36999Sbostic 	{
13*36999Sbostic 	if (nosignal) return;	/* don't do anything if inhibited */
14*36999Sbostic 	signal(SIGQUIT,SIG_IGN);	signal(SIGINT,SIG_IGN);
15*36999Sbostic 	quit(); if (predostuff==1) s2choose(); else showplayer();
16*36999Sbostic 	lflush();
17*36999Sbostic 	signal(SIGQUIT,cntlc);	signal(SIGINT,cntlc);
18*36999Sbostic 	}
19*36999Sbostic 
20*36999Sbostic /*
21*36999Sbostic  *	subroutine to save the game if a hangup signal
22*36999Sbostic  */
23*36999Sbostic static sgam()
24*36999Sbostic 	{
25*36999Sbostic 	savegame(savefilename);  wizard=1;  died(-257); /* hangup signal */
26*36999Sbostic 	}
27*36999Sbostic 
28*36999Sbostic #ifdef SIGTSTP
29*36999Sbostic static tstop() /* control Y	*/
30*36999Sbostic 	{
31*36999Sbostic 	if (nosignal)   return;  /* nothing if inhibited */
32*36999Sbostic 	lcreat((char*)0);  clearvt100();	lflush();	  signal(SIGTSTP,SIG_DFL);
33*36999Sbostic #ifdef SIGVTALRM
34*36999Sbostic 	/* looks like BSD4.2 or higher - must clr mask for signal to take effect*/
35*36999Sbostic 	sigsetmask(sigblock(0)& ~BIT(SIGTSTP));
36*36999Sbostic #endif
37*36999Sbostic 	kill(getpid(),SIGTSTP);
38*36999Sbostic 
39*36999Sbostic 	setupvt100();  signal(SIGTSTP,tstop);
40*36999Sbostic 	if (predostuff==1) s2choose(); else drawscreen();
41*36999Sbostic 	showplayer();	lflush();
42*36999Sbostic 	}
43*36999Sbostic #endif SIGTSTP
44*36999Sbostic 
45*36999Sbostic /*
46*36999Sbostic  *	subroutine to issue the needed signal traps  called from main()
47*36999Sbostic  */
48*36999Sbostic static sigill()  { sigpanic(SIGILL); }	 static sigtrap() { sigpanic(SIGTRAP); }
49*36999Sbostic static sigiot()  { sigpanic(SIGIOT); }   static sigemt()  { sigpanic(SIGEMT); }
50*36999Sbostic static sigfpe()  { sigpanic(SIGFPE); }   static sigbus()  { sigpanic(SIGBUS); }
51*36999Sbostic static sigsegv() { sigpanic(SIGSEGV); }  static sigsys()  { sigpanic(SIGSYS); }
52*36999Sbostic static sigpipe() { sigpanic(SIGPIPE); }  static sigterm() { sigpanic(SIGTERM); }
53*36999Sbostic sigsetup()
54*36999Sbostic 	{
55*36999Sbostic 	signal(SIGQUIT, cntlc); 		signal(SIGINT,  cntlc);
56*36999Sbostic 	signal(SIGKILL, SIG_IGN);		signal(SIGHUP,  sgam);
57*36999Sbostic 	signal(SIGILL,  sigill);		signal(SIGTRAP, sigtrap);
58*36999Sbostic 	signal(SIGIOT,  sigiot);		signal(SIGEMT,  sigemt);
59*36999Sbostic 	signal(SIGFPE,  sigfpe);		signal(SIGBUS,  sigbus);
60*36999Sbostic 	signal(SIGSEGV, sigsegv);		signal(SIGSYS,  sigsys);
61*36999Sbostic 	signal(SIGPIPE, sigpipe);		signal(SIGTERM, sigterm);
62*36999Sbostic #ifdef SIGTSTP
63*36999Sbostic 	signal(SIGTSTP,tstop);		signal(SIGSTOP,tstop);
64*36999Sbostic #endif SIGTSTP
65*36999Sbostic 	}
66*36999Sbostic 
67*36999Sbostic #ifdef BSD	/* for BSD UNIX? */
68*36999Sbostic 
69*36999Sbostic static char *signame[NSIG] = { "",
70*36999Sbostic "SIGHUP",  /*	1	 hangup */
71*36999Sbostic "SIGINT",  /*	2	 interrupt */
72*36999Sbostic "SIGQUIT", /*	3	 quit */
73*36999Sbostic "SIGILL",  /*	4	 illegal instruction (not reset when caught) */
74*36999Sbostic "SIGTRAP", /*	5	 trace trap (not reset when caught) */
75*36999Sbostic "SIGIOT",  /*	6	 IOT instruction */
76*36999Sbostic "SIGEMT",  /*	7	 EMT instruction */
77*36999Sbostic "SIGFPE",  /*	8	 floating point exception */
78*36999Sbostic "SIGKILL", /*	9	 kill (cannot be caught or ignored) */
79*36999Sbostic "SIGBUS",  /*	10	 bus error */
80*36999Sbostic "SIGSEGV", /*	11	 segmentation violation */
81*36999Sbostic "SIGSYS",  /*	12	 bad argument to system call */
82*36999Sbostic "SIGPIPE", /*	13	 write on a pipe with no one to read it */
83*36999Sbostic "SIGALRM", /*	14	 alarm clock */
84*36999Sbostic "SIGTERM", /*	15	 software termination signal from kill */
85*36999Sbostic "SIGURG",  /*	16	 urgent condition on IO channel */
86*36999Sbostic "SIGSTOP", /*	17	 sendable stop signal not from tty */
87*36999Sbostic "SIGTSTP", /*	18	 stop signal from tty */
88*36999Sbostic "SIGCONT", /*	19	 continue a stopped process */
89*36999Sbostic "SIGCHLD", /*	20	 to parent on child stop or exit */
90*36999Sbostic "SIGTTIN", /*	21	 to readers pgrp upon background tty read */
91*36999Sbostic "SIGTTOU", /*	22	 like TTIN for output if (tp->t_local&LTOSTOP) */
92*36999Sbostic "SIGIO",   /*	23	 input/output possible signal */
93*36999Sbostic "SIGXCPU", /*	24	 exceeded CPU time limit */
94*36999Sbostic "SIGXFSZ", /*	25	 exceeded file size limit */
95*36999Sbostic "SIGVTALRM",/*  26	 virtual time alarm */
96*36999Sbostic "SIGPROF", /*	27	 profiling time alarm */
97*36999Sbostic "","","","" };
98*36999Sbostic 
99*36999Sbostic #else BSD	/* for system V? */
100*36999Sbostic 
101*36999Sbostic static char *signame[NSIG] = { "",
102*36999Sbostic "SIGHUP",  /*	1	 hangup */
103*36999Sbostic "SIGINT",  /*	2	 interrupt */
104*36999Sbostic "SIGQUIT", /*	3	 quit */
105*36999Sbostic "SIGILL",  /*	4	 illegal instruction (not reset when caught) */
106*36999Sbostic "SIGTRAP", /*	5	 trace trap (not reset when caught) */
107*36999Sbostic "SIGIOT",  /*	6	 IOT instruction */
108*36999Sbostic "SIGEMT",  /*	7	 EMT instruction */
109*36999Sbostic "SIGFPE",  /*	8	 floating point exception */
110*36999Sbostic "SIGKILL", /*	9	 kill (cannot be caught or ignored) */
111*36999Sbostic "SIGBUS",  /*	10	 bus error */
112*36999Sbostic "SIGSEGV", /*	11	 segmentation violation */
113*36999Sbostic "SIGSYS",  /*	12	 bad argument to system call */
114*36999Sbostic "SIGPIPE", /*	13	 write on a pipe with no one to read it */
115*36999Sbostic "SIGALRM", /*	14	 alarm clock */
116*36999Sbostic "SIGTERM", /*	15	 software termination signal from kill */
117*36999Sbostic "SIGUSR1",  /*	16	 user defines signal 1 */
118*36999Sbostic "SIGUSR2", /*	17	 user defines signal 2 */
119*36999Sbostic "SIGCLD",  /*	18	 child death */
120*36999Sbostic "SIGPWR",  /*	19	 power fail */
121*36999Sbostic "","","","","","","","","","","","" };
122*36999Sbostic 
123*36999Sbostic #endif BSD
124*36999Sbostic 
125*36999Sbostic /*
126*36999Sbostic  *	routine to process a fatal error signal
127*36999Sbostic  */
128*36999Sbostic static sigpanic(sig)
129*36999Sbostic 	int sig;
130*36999Sbostic 	{
131*36999Sbostic 	char buf[128];
132*36999Sbostic 	signal(sig,SIG_DFL);
133*36999Sbostic 	sprintf(buf,"\nLarn - Panic! Signal %d received [%s]",sig,signame[sig]);
134*36999Sbostic 	write(2,buf,strlen(buf));  sleep(2);
135*36999Sbostic 	sncbr();
136*36999Sbostic 	savegame(savefilename);
137*36999Sbostic 	kill(getpid(),sig); /* this will terminate us */
138*36999Sbostic 	}
139