signal.c revision 1.2 1 /* $NetBSD: signal.c,v 1.2 1998/01/09 08:03:37 perry Exp $ */
2
3 /*
4 * Copyright (c) 1988 Mark Nudleman
5 * Copyright (c) 1988, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37 #ifndef lint
38 static char sccsid[] = "@(#)signal.c 8.1 (Berkeley) 6/6/93";
39 #endif /* not lint */
40
41 /*
42 * Routines dealing with signals.
43 *
44 * A signal usually merely causes a bit to be set in the "signals" word.
45 * At some convenient time, the mainline code checks to see if any
46 * signals need processing by calling psignal().
47 * If we happen to be reading from a file [in iread()] at the time
48 * the signal is received, we call intread to interrupt the iread.
49 */
50
51 #include <less.h>
52 #include <signal.h>
53
54 /*
55 * "sigs" contains bits indicating signals which need to be processed.
56 */
57 int sigs;
58
59 #ifdef SIGTSTP
60 #define S_STOP 02
61 #endif
62 #if defined(SIGWINCH) || defined(SIGWIND)
63 #define S_WINCH 04
64 #endif
65
66 extern int sc_width, sc_height;
67 extern int screen_trashed;
68 extern int lnloop;
69 extern int linenums;
70 extern int scroll;
71 extern int reading;
72
73 #ifdef SIGTSTP
74 /*
75 * "Stop" (^Z) signal handler.
76 */
77 static void
78 stop()
79 {
80 (void)signal(SIGTSTP, stop);
81 sigs |= S_STOP;
82 if (reading)
83 intread();
84 }
85 #endif
86
87 #ifdef SIGWINCH
88 /*
89 * "Window" change handler
90 */
91 void
92 winch()
93 {
94 (void)signal(SIGWINCH, winch);
95 sigs |= S_WINCH;
96 if (reading)
97 intread();
98 }
99 #else
100 #ifdef SIGWIND
101 /*
102 * "Window" change handler
103 */
104 winch()
105 {
106 (void)signal(SIGWIND, winch);
107 sigs |= S_WINCH;
108 if (reading)
109 intread();
110 }
111 #endif
112 #endif
113
114 static void
115 purgeandquit()
116 {
117
118 purge(); /* purge buffered output */
119 quit();
120 }
121
122 /*
123 * Set up the signal handlers.
124 */
125 init_signals(on)
126 int on;
127 {
128 if (on)
129 {
130 /*
131 * Set signal handlers.
132 */
133 (void)signal(SIGINT, purgeandquit);
134 #ifdef SIGTSTP
135 (void)signal(SIGTSTP, stop);
136 #endif
137 #ifdef SIGWINCH
138 (void)signal(SIGWINCH, winch);
139 #else
140 #ifdef SIGWIND
141 (void)signal(SIGWIND, winch);
142 #endif
143 #endif
144 } else
145 {
146 /*
147 * Restore signals to defaults.
148 */
149 (void)signal(SIGINT, SIG_DFL);
150 #ifdef SIGTSTP
151 (void)signal(SIGTSTP, SIG_DFL);
152 #endif
153 #ifdef SIGWINCH
154 (void)signal(SIGWINCH, SIG_IGN);
155 #endif
156 #ifdef SIGWIND
157 (void)signal(SIGWIND, SIG_IGN);
158 #endif
159 }
160 }
161
162 /*
163 * Process any signals we have received.
164 * A received signal cause a bit to be set in "sigs".
165 */
166 psignals()
167 {
168 register int tsignals;
169
170 if ((tsignals = sigs) == 0)
171 return;
172 sigs = 0;
173
174 #ifdef S_WINCH
175 if (tsignals & S_WINCH)
176 {
177 int old_width, old_height;
178 /*
179 * Re-execute get_term() to read the new window size.
180 */
181 old_width = sc_width;
182 old_height = sc_height;
183 get_term();
184 if (sc_width != old_width || sc_height != old_height)
185 {
186 scroll = (sc_height + 1) / 2;
187 screen_trashed = 1;
188 }
189 }
190 #endif
191 #ifdef SIGTSTP
192 if (tsignals & S_STOP)
193 {
194 /*
195 * Clean up the terminal.
196 */
197 #ifdef SIGTTOU
198 (void)signal(SIGTTOU, SIG_IGN);
199 #endif
200 lower_left();
201 clear_eol();
202 deinit();
203 (void)flush();
204 raw_mode(0);
205 #ifdef SIGTTOU
206 (void)signal(SIGTTOU, SIG_DFL);
207 #endif
208 (void)signal(SIGTSTP, SIG_DFL);
209 (void)kill(getpid(), SIGTSTP);
210 /*
211 * ... Bye bye. ...
212 * Hopefully we'll be back later and resume here...
213 * Reset the terminal and arrange to repaint the
214 * screen when we get back to the main command loop.
215 */
216 (void)signal(SIGTSTP, stop);
217 raw_mode(1);
218 init();
219 screen_trashed = 1;
220 }
221 #endif
222 }
223