Home | History | Annotate | Line # | Download | only in larn
signal.c revision 1.7
      1 /*	$NetBSD: signal.c,v 1.7 2001/02/05 00:57:34 christos Exp $	*/
      2 
      3 /* "Larn is copyrighted 1986 by Noah Morgan.\n" */
      4 
      5 #include <sys/cdefs.h>
      6 #ifndef lint
      7 __RCSID("$NetBSD: signal.c,v 1.7 2001/02/05 00:57:34 christos Exp $");
      8 #endif	/* not lint */
      9 
     10 #include <signal.h>
     11 #include <stdio.h>
     12 #include <string.h>
     13 #include <unistd.h>
     14 #include "header.h"
     15 #include "extern.h"
     16 
     17 static void s2choose __P((void));
     18 static void cntlc __P((int));
     19 static void sgam __P((int));
     20 static void tstop __P((int));
     21 static void sigpanic __P((int));
     22 
     23 #define BIT(a) (1<<((a)-1))
     24 
     25 static void
     26 s2choose()
     27 {				/* text to be displayed if ^C during intro
     28 				 * screen */
     29 	cursor(1, 24);
     30 	lprcat("Press ");
     31 	setbold();
     32 	lprcat("return");
     33 	resetbold();
     34 	lprcat(" to continue: ");
     35 	lflush();
     36 }
     37 
     38 static void
     39 cntlc(n)
     40 	int n;
     41 {				/* what to do for a ^C */
     42 	if (nosignal)
     43 		return;		/* don't do anything if inhibited */
     44 	signal(SIGQUIT, SIG_IGN);
     45 	signal(SIGINT, SIG_IGN);
     46 	quit();
     47 	if (predostuff == 1)
     48 		s2choose();
     49 	else
     50 		showplayer();
     51 	lflush();
     52 	signal(SIGQUIT, cntlc);
     53 	signal(SIGINT, cntlc);
     54 }
     55 
     56 /*
     57  *	subroutine to save the game if a hangup signal
     58  */
     59 static void
     60 sgam(n)
     61 	int n;
     62 {
     63 	savegame(savefilename);
     64 	wizard = 1;
     65 	died(-257);		/* hangup signal */
     66 }
     67 
     68 #ifdef SIGTSTP
     69 static void
     70 tstop(n)
     71 	int n;
     72 {				/* control Y	 */
     73 	if (nosignal)
     74 		return;		/* nothing if inhibited */
     75 	lcreat((char *) 0);
     76 	clearvt100();
     77 	lflush();
     78 	signal(SIGTSTP, SIG_DFL);
     79 #ifdef SIGVTALRM
     80 	/*
     81 	 * looks like BSD4.2 or higher - must clr mask for signal to take
     82 	 * effect
     83 	 */
     84 	sigsetmask(sigblock(0) & ~BIT(SIGTSTP));
     85 #endif
     86 	kill(getpid(), SIGTSTP);
     87 
     88 	setupvt100();
     89 	signal(SIGTSTP, tstop);
     90 	if (predostuff == 1)
     91 		s2choose();
     92 	else
     93 		drawscreen();
     94 	showplayer();
     95 	lflush();
     96 }
     97 #endif	/* SIGTSTP */
     98 
     99 /*
    100  *	subroutine to issue the needed signal traps  called from main()
    101  */
    102 void
    103 sigsetup()
    104 {
    105 	signal(SIGQUIT, cntlc);
    106 	signal(SIGINT, cntlc);
    107 	signal(SIGKILL, SIG_IGN);
    108 	signal(SIGHUP, sgam);
    109 	signal(SIGILL, sigpanic);
    110 	signal(SIGTRAP, sigpanic);
    111 	signal(SIGIOT, sigpanic);
    112 	signal(SIGEMT, sigpanic);
    113 	signal(SIGFPE, sigpanic);
    114 	signal(SIGBUS, sigpanic);
    115 	signal(SIGSEGV, sigpanic);
    116 	signal(SIGSYS, sigpanic);
    117 	signal(SIGPIPE, sigpanic);
    118 	signal(SIGTERM, sigpanic);
    119 #ifdef SIGTSTP
    120 	signal(SIGTSTP, tstop);
    121 	signal(SIGSTOP, tstop);
    122 #endif	/* SIGTSTP */
    123 }
    124 
    125 /*
    126  *	routine to process a fatal error signal
    127  */
    128 static void
    129 sigpanic(sig)
    130 	int             sig;
    131 {
    132 	char            buf[128];
    133 	signal(sig, SIG_DFL);
    134 	snprintf(buf, sizeof(buf),
    135 	    "\nLarn - Panic! Signal %d received [SIG%s]", sig,
    136 	    sys_signame[sig]);
    137 	write(2, buf, strlen(buf));
    138 	sleep(2);
    139 	sncbr();
    140 	savegame(savefilename);
    141 	kill(getpid(), sig);	/* this will terminate us */
    142 }
    143