]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/miscellany/less-177/signal.c
ap: Fix write past end of addrs[] array.
[nmh] / docs / historical / mh-6.8.5 / miscellany / less-177 / signal.c
1 /*
2 * Routines dealing with signals.
3 *
4 * A signal usually merely causes a bit to be set in the "signals" word.
5 * At some convenient time, the mainline code checks to see if any
6 * signals need processing by calling psignal().
7 * If we happen to be reading from a file [in iread()] at the time
8 * the signal is received, we call intread to interrupt the iread.
9 */
10
11 #include "less.h"
12 #include <signal.h>
13
14 /*
15 * "sigs" contains bits indicating signals which need to be processed.
16 */
17 public int sigs;
18
19 #define S_INTERRUPT 01
20 #ifdef SIGTSTP
21 #define S_STOP 02
22 #endif
23 #if defined(SIGWINCH) || defined(SIGWIND)
24 #define S_WINCH 04
25 #endif
26
27 extern int sc_width, sc_height;
28 extern int swindow;
29 extern int screen_trashed;
30 extern int lnloop;
31 extern int linenums;
32 extern int scroll;
33 extern int reading;
34
35 /*
36 * Interrupt signal handler.
37 */
38 /* ARGSUSED*/
39 static HANDLER
40 u_interrupt(type)
41 int type;
42 {
43 SIGNAL(SIGINT, u_interrupt);
44 sigs |= S_INTERRUPT;
45 if (reading)
46 intread();
47 }
48
49 public void
50 fake_interrupt()
51 {
52 sigs |= S_INTERRUPT;
53 }
54
55 #ifdef SIGTSTP
56 /*
57 * "Stop" (^Z) signal handler.
58 */
59 /* ARGSUSED*/
60 static HANDLER
61 stop(type)
62 int type;
63 {
64 SIGNAL(SIGTSTP, stop);
65 sigs |= S_STOP;
66 if (reading)
67 intread();
68 }
69 #endif
70
71 #ifdef SIGWINCH
72 /*
73 * "Window" change handler
74 */
75 /* ARGSUSED*/
76 public HANDLER
77 winch(type)
78 int type;
79 {
80 SIGNAL(SIGWINCH, winch);
81 sigs |= S_WINCH;
82 if (reading)
83 intread();
84 }
85 #else
86 #ifdef SIGWIND
87 /*
88 * "Window" change handler
89 */
90 /* ARGSUSED*/
91 public HANDLER
92 winch(type)
93 int type;
94 {
95 SIGNAL(SIGWIND, winch);
96 sigs |= S_WINCH;
97 if (reading)
98 intread();
99 }
100 #endif
101 #endif
102
103 /*
104 * Set up the signal handlers.
105 */
106 public void
107 init_signals(on)
108 int on;
109 {
110 if (on)
111 {
112 /*
113 * Set signal handlers.
114 */
115 (void) SIGNAL(SIGINT, u_interrupt);
116 #ifdef SIGTSTP
117 (void) SIGNAL(SIGTSTP, stop);
118 #endif
119 #ifdef SIGWINCH
120 (void) SIGNAL(SIGWINCH, winch);
121 #else
122 #ifdef SIGWIND
123 (void) SIGNAL(SIGWIND, winch);
124 #endif
125 #endif
126 } else
127 {
128 /*
129 * Restore signals to defaults.
130 */
131 (void) SIGNAL(SIGINT, SIG_DFL);
132 #ifdef SIGTSTP
133 (void) SIGNAL(SIGTSTP, SIG_DFL);
134 #endif
135 #ifdef SIGWINCH
136 (void) SIGNAL(SIGWINCH, SIG_IGN);
137 #endif
138 #ifdef SIGWIND
139 (void) SIGNAL(SIGWIND, SIG_IGN);
140 #endif
141 }
142 }
143
144 /*
145 * Process any signals we have received.
146 * A received signal cause a bit to be set in "sigs".
147 */
148 public void
149 psignals()
150 {
151 register int tsignals;
152
153 if ((tsignals = sigs) == 0)
154 return;
155 sigs = 0;
156
157 #ifdef S_WINCH
158 if (tsignals & S_WINCH)
159 {
160 int old_width, old_height;
161 /*
162 * Re-execute get_term() to read the new window size.
163 */
164 old_width = sc_width;
165 old_height = sc_height;
166 swindow = -1;
167 get_term();
168 if (sc_width != old_width || sc_height != old_height)
169 {
170 scroll = (sc_height + 1) / 2;
171 screen_trashed = 1;
172 }
173 }
174 #endif
175 #ifdef SIGTSTP
176 if (tsignals & S_STOP)
177 {
178 /*
179 * Clean up the terminal.
180 */
181 #ifdef SIGTTOU
182 SIGNAL(SIGTTOU, SIG_IGN);
183 #endif
184 lower_left();
185 clear_eol();
186 deinit();
187 flush();
188 raw_mode(0);
189 #ifdef SIGTTOU
190 SIGNAL(SIGTTOU, SIG_DFL);
191 #endif
192 SIGNAL(SIGTSTP, SIG_DFL);
193 kill(getpid(), SIGTSTP);
194 /*
195 * ... Bye bye. ...
196 * Hopefully we'll be back later and resume here...
197 * Reset the terminal and arrange to repaint the
198 * screen when we get back to the main command loop.
199 */
200 SIGNAL(SIGTSTP, stop);
201 raw_mode(1);
202 init();
203 screen_trashed = 1;
204 }
205 #endif
206 if (tsignals & S_INTERRUPT)
207 {
208 bell();
209 /*
210 * {{ You may wish to replace the bell() with
211 * error("Interrupt", NULL_PARG); }}
212 */
213
214 /*
215 * If we were interrupted while in the "calculating
216 * line numbers" loop, turn off line numbers.
217 */
218 if (lnloop)
219 {
220 lnloop = 0;
221 if (linenums == 2)
222 screen_trashed = 1;
223 linenums = 0;
224 error("Line numbers turned off", NULL_PARG);
225 }
226
227 }
228 }