This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / usr.bin / more / signal.c
CommitLineData
2ec5f51d
NW
1/*
2 * Copyright (c) 1988 Mark Nudleman
3 * Copyright (c) 1988 Regents of the University of California.
4 * 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
36static char sccsid[] = "@(#)signal.c 5.8 (Berkeley) 3/1/91";
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 */
55int 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
64extern int sc_width, sc_height;
65extern int screen_trashed;
66extern int lnloop;
67extern int linenums;
68extern int scroll;
69extern int reading;
70
71#ifdef SIGTSTP
72/*
73 * "Stop" (^Z) signal handler.
74 */
75static void
76stop()
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 */
89void
90winch()
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 */
102winch()
103{
104 (void)signal(SIGWIND, winch);
105 sigs |= S_WINCH;
106 if (reading)
107 intread();
108}
109#endif
110#endif
111
112static void
113purgeandquit()
114{
115
116 purge(); /* purge buffered output */
117 quit();
118}
119
120/*
121 * Set up the signal handlers.
122 */
123init_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 */
164psignals()
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}