Home | History | Annotate | Line # | Download | only in larn
      1 /*	$NetBSD: signal.c,v 1.9 2012/06/19 05:30:44 dholland 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.9 2012/06/19 05:30:44 dholland 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(void);
     18 static void cntlc(int);
     19 static void sgam(int);
     20 static void tstop(int);
     21 static void sigpanic(int);
     22 
     23 #define BIT(a) (1<<((a)-1))
     24 
     25 static void
     26 s2choose(void)
     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(int n)
     40 {				/* what to do for a ^C */
     41 	if (nosignal)
     42 		return;		/* don't do anything if inhibited */
     43 	signal(SIGQUIT, SIG_IGN);
     44 	signal(SIGINT, SIG_IGN);
     45 	quit();
     46 	if (predostuff == 1)
     47 		s2choose();
     48 	else
     49 		showplayer();
     50 	lflush();
     51 	signal(SIGQUIT, cntlc);
     52 	signal(SIGINT, cntlc);
     53 }
     54 
     55 /*
     56  *	subroutine to save the game if a hangup signal
     57  */
     58 static void
     59 sgam(int n)
     60 {
     61 	savegame(savefilename);
     62 	wizard = 1;
     63 	died(-257);		/* hangup signal */
     64 }
     65 
     66 #ifdef SIGTSTP
     67 static void
     68 tstop(int n)
     69 {				/* control Y	 */
     70 	if (nosignal)
     71 		return;		/* nothing if inhibited */
     72 	lcreat((char *) 0);
     73 	clearvt100();
     74 	lflush();
     75 	signal(SIGTSTP, SIG_DFL);
     76 #ifdef SIGVTALRM
     77 	/*
     78 	 * looks like BSD4.2 or higher - must clr mask for signal to take
     79 	 * effect
     80 	 */
     81 	sigsetmask(sigblock(0) & ~BIT(SIGTSTP));
     82 #endif
     83 	kill(getpid(), SIGTSTP);
     84 
     85 	setupvt100();
     86 	signal(SIGTSTP, tstop);
     87 	if (predostuff == 1)
     88 		s2choose();
     89 	else
     90 		drawscreen();
     91 	showplayer();
     92 	lflush();
     93 }
     94 #endif	/* SIGTSTP */
     95 
     96 /*
     97  *	subroutine to issue the needed signal traps  called from main()
     98  */
     99 void
    100 sigsetup(void)
    101 {
    102 	signal(SIGQUIT, cntlc);
    103 	signal(SIGINT, cntlc);
    104 	signal(SIGKILL, SIG_IGN);
    105 	signal(SIGHUP, sgam);
    106 	signal(SIGILL, sigpanic);
    107 	signal(SIGTRAP, sigpanic);
    108 	signal(SIGIOT, sigpanic);
    109 	signal(SIGEMT, sigpanic);
    110 	signal(SIGFPE, sigpanic);
    111 	signal(SIGBUS, sigpanic);
    112 	signal(SIGSEGV, sigpanic);
    113 	signal(SIGSYS, sigpanic);
    114 	signal(SIGPIPE, sigpanic);
    115 	signal(SIGTERM, sigpanic);
    116 #ifdef SIGTSTP
    117 	signal(SIGTSTP, tstop);
    118 	signal(SIGSTOP, tstop);
    119 #endif	/* SIGTSTP */
    120 }
    121 
    122 /*
    123  *	routine to process a fatal error signal
    124  */
    125 static void
    126 sigpanic(int sig)
    127 {
    128 	char            buf[128];
    129 	signal(sig, SIG_DFL);
    130 	snprintf(buf, sizeof(buf),
    131 	    "\nLarn - Panic! Signal %d received [SIG%s]", sig,
    132 	    sys_signame[sig]);
    133 	write(2, buf, strlen(buf));
    134 	sleep(2);
    135 	sncbr();
    136 	savegame(savefilename);
    137 	kill(getpid(), sig);	/* this will terminate us */
    138 }
    139