Home | History | Annotate | Line # | Download | only in warp
      1 /* Header: /usr/src/games/warp/RCS/sig.c,v 1.1 87/07/03 01:47:11 games Exp */
      2 
      3 /* Log:	sig.c,v
      4  * Revision 7.0.1.1a  87/07/03  01:47:11  games
      5  * Changed sigsetmask to use sigmask instead of calculating it (incorrectly)
      6  * by hand.
      7  *
      8  * Revision 7.0.1.1  86/12/12  17:02:44  lwall
      9  * Baseline for net release.
     10  *
     11  * Revision 7.0  86/10/08  15:13:24  lwall
     12  * Split into separate files.  Added amoebas and pirates.
     13  *
     14  */
     15 
     16 #include "EXTERN.h"
     17 #include "warp.h"
     18 #include "play.h"
     19 #include "score.h"
     20 #include "term.h"
     21 #include "util.h"
     22 #include "INTERN.h"
     23 #include "sig.h"
     24 
     25 void
     26 sig_init(void)
     27 {
     28     sigignore(SIGINT);  /* for inquiry of existence via kill call */
     29 #ifdef SIGTTOU
     30     sigignore(SIGTTOU);
     31 #endif
     32 
     33     sigset(SIGHUP, sig_catcher);
     34     if (!debugging) {
     35 	sigset(SIGQUIT, sig_catcher);
     36 	sigset(SIGILL, sig_catcher);
     37 	sigset(SIGFPE, sig_catcher);
     38 #if 0
     39 	sigset(SIGBUS, sig_catcher);
     40 	sigset(SIGSEGV, sig_catcher);
     41 #endif
     42 	sigset(SIGSYS, sig_catcher);
     43 	sigset(SIGTERM, sig_catcher);
     44     }
     45 #ifdef SIGXCPU
     46     sigset(SIGXCPU, sig_catcher);
     47 #endif
     48 #ifdef SIGCONT
     49     sigset(SIGCONT, cont_catcher);
     50 #endif
     51 #ifdef SIGTSTP
     52     sigset(SIGTSTP, stop_catcher);
     53     sigset(SIGSTOP, stop_catcher);
     54 #endif
     55 }
     56 
     57 #ifdef SIGTSTP
     58 void
     59 cont_catcher(int x)
     60 {
     61 #ifndef lint
     62     sigset(SIGCONT,cont_catcher);
     63 #endif
     64     savetty();
     65     crmode();
     66     raw();
     67     noecho();
     68     nonl();
     69 }
     70 #endif
     71 
     72 void
     73 mytstp(void)
     74 {
     75     resetty();
     76 #ifdef SIGTSTP
     77     kill(0,SIGTSTP);
     78 #else
     79     if (fork())
     80 	wait(0);
     81     else {
     82 	char *shell = getenv("SHELL");
     83 
     84 	setuid(getuid());
     85 	if (!*shell)
     86 	    shell = "/bin/sh";
     87 	execl(shell,shell,0);
     88 	exit(1);
     89     }
     90 #endif
     91     rewrite();
     92 }
     93 
     94 void					/* very much void */
     95 finalize(int status)
     96 {
     97     if (bizarre)
     98 	resetty();
     99     if (status < 0) {
    100 	chdir("/usr/tmp");
    101 	sigset(SIGILL,SIG_DFL);
    102 	abort();
    103     }
    104     exit(status);
    105 }
    106 
    107 /* come here on signal other than interrupt, stop, or cont */
    108 
    109 void
    110 sig_catcher(int signo)
    111 {
    112 #ifdef VERBOSE
    113     static const char *signame[] = {
    114 	"",
    115 	"HUP",
    116 	"INT",
    117 	"QUIT",
    118 	"ILL",
    119 	"TRAP",
    120 	"IOT",
    121 	"EMT",
    122 	"FPE",
    123 	"KILL",
    124 	"BUS",
    125 	"SEGV",
    126 	"SYS",
    127 	"PIPE",
    128 	"ALRM",
    129 	"TERM",
    130 	"???"
    131 #ifdef SIGTSTP
    132 	,"STOP",
    133 	"TSTP",
    134 	"CONT",
    135 	"CHLD",
    136 	"TTIN",
    137 	"TTOU",
    138 	"TINT",
    139 	"XCPU",
    140 	"XFSZ"
    141 #ifdef SIGPROF
    142 	,"VTALARM",
    143 	"PROF"
    144 #endif
    145 #endif
    146 	};
    147 #endif
    148 
    149 #ifdef SIGTTOU
    150 #ifndef lint
    151     sigignore(SIGTTOU);
    152 #endif /* lint */
    153 #endif
    154 #ifdef DEBUGGING
    155     if (debug) {
    156 	printf("\r\nSIG%s--game not saved in debug\r\n",signame[signo]);
    157 	finalize(-1);
    158     }
    159 #endif
    160     panic++;
    161     if (panic >= 2) {
    162 	if (panic >= 3)
    163 	    abort();
    164 	chdir(SAVEDIR);
    165 	kill(0,SIGIOT);
    166     }
    167     (void) sigset(SIGILL,SIG_DFL);
    168     if (signo == SIGHUP && (timer < 10 || didkill))
    169 	signo = SIGQUIT;
    170     if (signo == SIGQUIT) {	/* can't let them bomb out without penalty */
    171 	if (smarts < 20)
    172 	    smarts += 4;
    173 	else if (smarts < 35)
    174 	    smarts += 2;
    175 	else
    176 	    smarts++;
    177 	totalscore -= possiblescore / 2;
    178     }
    179     save_game();
    180     if (signo != SIGHUP && signo != SIGQUIT) {
    181 #ifdef VERBOSE
    182 	IF(verbose)
    183 	    printf("\r\nCaught %s%s--%s\r\n",
    184 		signo ? "a SIG" : "an internal error", signame[signo],
    185 		experimenting ? "game saved" : "bye bye");
    186 	ELSE
    187 #endif
    188 #ifdef TERSE
    189 	    printf("\r\nsignal %d--bye bye\r\n",signo);
    190 #endif
    191     }
    192     switch (signo) {
    193     case SIGBUS:
    194     case SIGILL:
    195     case SIGSEGV:
    196 	finalize(-signo);
    197     }
    198     finalize(1);				/* and blow up */
    199 }
    200 
    201 #ifdef SIGTSTP
    202 /* come here on stop signal */
    203 
    204 void
    205 stop_catcher(int sig)
    206 {
    207     if (!waiting) {
    208 	resetty();			/* this is the point of all this */
    209 #ifdef DEBUGGING
    210 	if (debug)
    211 	    write(2,"stop_catcher\r\n",13);
    212 #endif
    213 	sigset(SIGTSTP,SIG_DFL);	/* enable stop */
    214 #ifdef BSD42
    215 	sigsetmask(sigblock(0L) & ~sigmask(SIGTSTP));
    216 #endif
    217 	kill(0,SIGTSTP);		/* and do the stop */
    218     }
    219 #ifndef lint
    220     sigset(SIGTSTP,stop_catcher);	/* unenable the stop */
    221 #endif
    222 }
    223 #endif
    224