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