Commit | Line | Data |
---|---|---|
9546bac0 WJ |
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<OSTOP) */ | |
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 | } |