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