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