signal.c revision 1.9 1 1.9 dholland /* $NetBSD: signal.c,v 1.9 2012/06/19 05:30:44 dholland 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.9 dholland __RCSID("$NetBSD: signal.c,v 1.9 2012/06/19 05:30:44 dholland 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.8 jsm static void s2choose(void);
18 1.8 jsm static void cntlc(int);
19 1.8 jsm static void sgam(int);
20 1.8 jsm static void tstop(int);
21 1.8 jsm static void sigpanic(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.9 dholland s2choose(void)
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.9 dholland cntlc(int n)
40 1.6 christos { /* what to do for a ^C */
41 1.6 christos if (nosignal)
42 1.6 christos return; /* don't do anything if inhibited */
43 1.6 christos signal(SIGQUIT, SIG_IGN);
44 1.6 christos signal(SIGINT, SIG_IGN);
45 1.6 christos quit();
46 1.6 christos if (predostuff == 1)
47 1.6 christos s2choose();
48 1.6 christos else
49 1.6 christos showplayer();
50 1.6 christos lflush();
51 1.6 christos signal(SIGQUIT, cntlc);
52 1.6 christos signal(SIGINT, cntlc);
53 1.6 christos }
54 1.1 cgd
55 1.1 cgd /*
56 1.1 cgd * subroutine to save the game if a hangup signal
57 1.1 cgd */
58 1.1 cgd static void
59 1.9 dholland sgam(int n)
60 1.6 christos {
61 1.6 christos savegame(savefilename);
62 1.6 christos wizard = 1;
63 1.6 christos died(-257); /* hangup signal */
64 1.6 christos }
65 1.1 cgd
66 1.1 cgd #ifdef SIGTSTP
67 1.1 cgd static void
68 1.9 dholland tstop(int n)
69 1.6 christos { /* control Y */
70 1.6 christos if (nosignal)
71 1.6 christos return; /* nothing if inhibited */
72 1.6 christos lcreat((char *) 0);
73 1.6 christos clearvt100();
74 1.6 christos lflush();
75 1.6 christos signal(SIGTSTP, SIG_DFL);
76 1.1 cgd #ifdef SIGVTALRM
77 1.6 christos /*
78 1.6 christos * looks like BSD4.2 or higher - must clr mask for signal to take
79 1.6 christos * effect
80 1.6 christos */
81 1.6 christos sigsetmask(sigblock(0) & ~BIT(SIGTSTP));
82 1.1 cgd #endif
83 1.6 christos kill(getpid(), SIGTSTP);
84 1.1 cgd
85 1.6 christos setupvt100();
86 1.6 christos signal(SIGTSTP, tstop);
87 1.6 christos if (predostuff == 1)
88 1.6 christos s2choose();
89 1.6 christos else
90 1.6 christos drawscreen();
91 1.6 christos showplayer();
92 1.6 christos lflush();
93 1.6 christos }
94 1.6 christos #endif /* SIGTSTP */
95 1.1 cgd
96 1.1 cgd /*
97 1.1 cgd * subroutine to issue the needed signal traps called from main()
98 1.1 cgd */
99 1.6 christos void
100 1.9 dholland sigsetup(void)
101 1.6 christos {
102 1.6 christos signal(SIGQUIT, cntlc);
103 1.6 christos signal(SIGINT, cntlc);
104 1.6 christos signal(SIGKILL, SIG_IGN);
105 1.6 christos signal(SIGHUP, sgam);
106 1.6 christos signal(SIGILL, sigpanic);
107 1.6 christos signal(SIGTRAP, sigpanic);
108 1.6 christos signal(SIGIOT, sigpanic);
109 1.6 christos signal(SIGEMT, sigpanic);
110 1.6 christos signal(SIGFPE, sigpanic);
111 1.6 christos signal(SIGBUS, sigpanic);
112 1.6 christos signal(SIGSEGV, sigpanic);
113 1.6 christos signal(SIGSYS, sigpanic);
114 1.6 christos signal(SIGPIPE, sigpanic);
115 1.6 christos signal(SIGTERM, sigpanic);
116 1.1 cgd #ifdef SIGTSTP
117 1.6 christos signal(SIGTSTP, tstop);
118 1.6 christos signal(SIGSTOP, tstop);
119 1.6 christos #endif /* SIGTSTP */
120 1.6 christos }
121 1.1 cgd
122 1.1 cgd /*
123 1.1 cgd * routine to process a fatal error signal
124 1.1 cgd */
125 1.1 cgd static void
126 1.9 dholland sigpanic(int sig)
127 1.6 christos {
128 1.6 christos char buf[128];
129 1.6 christos signal(sig, SIG_DFL);
130 1.7 christos snprintf(buf, sizeof(buf),
131 1.7 christos "\nLarn - Panic! Signal %d received [SIG%s]", sig,
132 1.7 christos sys_signame[sig]);
133 1.6 christos write(2, buf, strlen(buf));
134 1.6 christos sleep(2);
135 1.1 cgd sncbr();
136 1.6 christos savegame(savefilename);
137 1.6 christos kill(getpid(), sig); /* this will terminate us */
138 1.6 christos }
139