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