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