b4c0a2072ef4ab183bbb3f315a19a96042beec0d
[dragonfly.git] / games / larn / signal.c
1 #include <signal.h>
2 #include "header.h"                     /* "Larn is copyrighted 1986 by Noah Morgan.\n" */
3 #define BIT(a) (1<<((a)-1))
4 extern char savefilename[],wizard,predostuff,nosignal;
5 static s2choose()       /* text to be displayed if ^C during intro screen */
6         {
7         cursor(1,24); lprcat("Press "); setbold(); lprcat("return"); resetbold();
8         lprcat(" to continue: ");   lflush();
9         }
10
11 static void
12 cntlc() /* what to do for a ^C */
13         {
14         if (nosignal) return;   /* don't do anything if inhibited */
15         signal(SIGQUIT,SIG_IGN);        signal(SIGINT,SIG_IGN);
16         quit(); if (predostuff==1) s2choose(); else showplayer();
17         lflush();
18         signal(SIGQUIT,cntlc);  signal(SIGINT,cntlc);
19         }
20
21 /*
22  *      subroutine to save the game if a hangup signal
23  */
24 static void
25 sgam()
26         {
27         savegame(savefilename);  wizard=1;  died(-257); /* hangup signal */
28         }
29
30 #ifdef SIGTSTP
31 static void
32 tstop() /* control Y    */
33         {
34         if (nosignal)   return;  /* nothing if inhibited */
35         lcreat((char*)0);  clearvt100();        lflush();         signal(SIGTSTP,SIG_DFL);
36 #ifdef SIGVTALRM
37         /* looks like BSD4.2 or higher - must clr mask for signal to take effect*/
38         sigsetmask(sigblock(0)& ~BIT(SIGTSTP));
39 #endif
40         kill(getpid(),SIGTSTP);
41
42         setupvt100();  signal(SIGTSTP,tstop);
43         if (predostuff==1) s2choose(); else drawscreen();
44         showplayer();   lflush();
45         }
46 #endif SIGTSTP
47
48 /*
49  *      subroutine to issue the needed signal traps  called from main()
50  */
51 static void sigpanic();
52 static void sigill()    { sigpanic(SIGILL); }
53 static void sigtrap()   { sigpanic(SIGTRAP); }
54 static void sigiot()    { sigpanic(SIGIOT); }
55 static void sigemt()    { sigpanic(SIGEMT); }
56 static void sigfpe()    { sigpanic(SIGFPE); }
57 static void sigbus()    { sigpanic(SIGBUS); }
58 static void sigsegv()   { sigpanic(SIGSEGV); }
59 static void sigsys()    { sigpanic(SIGSYS); }
60 static void sigpipe()   { sigpanic(SIGPIPE); }
61 static void sigterm()   { sigpanic(SIGTERM); }
62 sigsetup()
63         {
64         signal(SIGQUIT, cntlc);                 signal(SIGINT,  cntlc);
65         signal(SIGKILL, SIG_IGN);               signal(SIGHUP,  sgam);
66         signal(SIGILL,  sigill);                signal(SIGTRAP, sigtrap);
67         signal(SIGIOT,  sigiot);                signal(SIGEMT,  sigemt);
68         signal(SIGFPE,  sigfpe);                signal(SIGBUS,  sigbus);
69         signal(SIGSEGV, sigsegv);               signal(SIGSYS,  sigsys);
70         signal(SIGPIPE, sigpipe);               signal(SIGTERM, sigterm);
71 #ifdef SIGTSTP
72         signal(SIGTSTP,tstop);          signal(SIGSTOP,tstop);
73 #endif SIGTSTP
74         }
75
76 #ifdef BSD      /* for BSD UNIX? */
77
78 static char *signame[NSIG] = { "",
79 "SIGHUP",  /*   1        hangup */
80 "SIGINT",  /*   2        interrupt */
81 "SIGQUIT", /*   3        quit */
82 "SIGILL",  /*   4        illegal instruction (not reset when caught) */
83 "SIGTRAP", /*   5        trace trap (not reset when caught) */
84 "SIGIOT",  /*   6        IOT instruction */
85 "SIGEMT",  /*   7        EMT instruction */
86 "SIGFPE",  /*   8        floating point exception */
87 "SIGKILL", /*   9        kill (cannot be caught or ignored) */
88 "SIGBUS",  /*   10       bus error */
89 "SIGSEGV", /*   11       segmentation violation */
90 "SIGSYS",  /*   12       bad argument to system call */
91 "SIGPIPE", /*   13       write on a pipe with no one to read it */
92 "SIGALRM", /*   14       alarm clock */
93 "SIGTERM", /*   15       software termination signal from kill */
94 "SIGURG",  /*   16       urgent condition on IO channel */
95 "SIGSTOP", /*   17       sendable stop signal not from tty */
96 "SIGTSTP", /*   18       stop signal from tty */
97 "SIGCONT", /*   19       continue a stopped process */
98 "SIGCHLD", /*   20       to parent on child stop or exit */
99 "SIGTTIN", /*   21       to readers pgrp upon background tty read */
100 "SIGTTOU", /*   22       like TTIN for output if (tp->t_local&LTOSTOP) */
101 "SIGIO",   /*   23       input/output possible signal */
102 "SIGXCPU", /*   24       exceeded CPU time limit */
103 "SIGXFSZ", /*   25       exceeded file size limit */
104 "SIGVTALRM",/*  26       virtual time alarm */
105 "SIGPROF", /*   27       profiling time alarm */
106 "","","","" };
107
108 #else BSD       /* for system V? */
109
110 static char *signame[NSIG] = { "",
111 "SIGHUP",  /*   1        hangup */
112 "SIGINT",  /*   2        interrupt */
113 "SIGQUIT", /*   3        quit */
114 "SIGILL",  /*   4        illegal instruction (not reset when caught) */
115 "SIGTRAP", /*   5        trace trap (not reset when caught) */
116 "SIGIOT",  /*   6        IOT instruction */
117 "SIGEMT",  /*   7        EMT instruction */
118 "SIGFPE",  /*   8        floating point exception */
119 "SIGKILL", /*   9        kill (cannot be caught or ignored) */
120 "SIGBUS",  /*   10       bus error */
121 "SIGSEGV", /*   11       segmentation violation */
122 "SIGSYS",  /*   12       bad argument to system call */
123 "SIGPIPE", /*   13       write on a pipe with no one to read it */
124 "SIGALRM", /*   14       alarm clock */
125 "SIGTERM", /*   15       software termination signal from kill */
126 "SIGUSR1",  /*  16       user defines signal 1 */
127 "SIGUSR2", /*   17       user defines signal 2 */
128 "SIGCLD",  /*   18       child death */
129 "SIGPWR",  /*   19       power fail */
130 "","","","","","","","","","","","" };
131
132 #endif BSD
133
134 /*
135  *      routine to process a fatal error signal
136  */
137 static void
138 sigpanic(sig)
139         int sig;
140         {
141         char buf[128];
142         signal(sig,SIG_DFL);
143         sprintf(buf,"\nLarn - Panic! Signal %d received [%s]",sig,signame[sig]);
144         write(2,buf,strlen(buf));  sleep(2);
145         sncbr();
146         savegame(savefilename);
147         kill(getpid(),sig); /* this will terminate us */
148         }