add ":a[rgs]" command from vi
[unix-history] / usr / src / usr.bin / more / signal.c
... / ...
CommitLineData
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 are permitted
7 * provided that the above copyright notice and this paragraph are
8 * duplicated in all such forms and that any documentation,
9 * advertising materials, and other materials related to such
10 * distribution and use acknowledge that the software was developed
11 * by Mark Nudleman and the University of California, Berkeley. The
12 * name of Mark Nudleman or the
13 * University may not be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 */
19
20#ifndef lint
21static char sccsid[] = "@(#)signal.c 5.6 (Berkeley) %G%";
22#endif /* not lint */
23
24/*
25 * Routines dealing with signals.
26 *
27 * A signal usually merely causes a bit to be set in the "signals" word.
28 * At some convenient time, the mainline code checks to see if any
29 * signals need processing by calling psignal().
30 * If we happen to be reading from a file [in iread()] at the time
31 * the signal is received, we call intread to interrupt the iread.
32 */
33
34#include <less.h>
35#include <signal.h>
36
37/*
38 * "sigs" contains bits indicating signals which need to be processed.
39 */
40int sigs;
41
42#ifdef SIGTSTP
43#define S_STOP 02
44#endif
45#if defined(SIGWINCH) || defined(SIGWIND)
46#define S_WINCH 04
47#endif
48
49extern int sc_width, sc_height;
50extern int screen_trashed;
51extern int lnloop;
52extern int linenums;
53extern int scroll;
54extern int reading;
55
56#ifdef SIGTSTP
57/*
58 * "Stop" (^Z) signal handler.
59 */
60static
61stop()
62{
63 (void)signal(SIGTSTP, stop);
64 sigs |= S_STOP;
65 if (reading)
66 intread();
67}
68#endif
69
70#ifdef SIGWINCH
71/*
72 * "Window" change handler
73 */
74winch()
75{
76 (void)signal(SIGWINCH, winch);
77 sigs |= S_WINCH;
78 if (reading)
79 intread();
80}
81#else
82#ifdef SIGWIND
83/*
84 * "Window" change handler
85 */
86winch()
87{
88 (void)signal(SIGWIND, winch);
89 sigs |= S_WINCH;
90 if (reading)
91 intread();
92}
93#endif
94#endif
95
96static int
97purgeandquit()
98{
99
100 purge(); /* purge buffered output */
101 quit();
102}
103
104/*
105 * Set up the signal handlers.
106 */
107init_signals(on)
108 int on;
109{
110 int quit();
111
112 if (on)
113 {
114 /*
115 * Set signal handlers.
116 */
117 (void)signal(SIGINT, purgeandquit);
118#ifdef SIGTSTP
119 (void)signal(SIGTSTP, stop);
120#endif
121#ifdef SIGWINCH
122 (void)signal(SIGWINCH, winch);
123#else
124#ifdef SIGWIND
125 (void)signal(SIGWIND, winch);
126#endif
127#endif
128 } else
129 {
130 /*
131 * Restore signals to defaults.
132 */
133 (void)signal(SIGINT, SIG_DFL);
134#ifdef SIGTSTP
135 (void)signal(SIGTSTP, SIG_DFL);
136#endif
137#ifdef SIGWINCH
138 (void)signal(SIGWINCH, SIG_IGN);
139#endif
140#ifdef SIGWIND
141 (void)signal(SIGWIND, SIG_IGN);
142#endif
143 }
144}
145
146/*
147 * Process any signals we have received.
148 * A received signal cause a bit to be set in "sigs".
149 */
150psignals()
151{
152 register int tsignals;
153
154 if ((tsignals = sigs) == 0)
155 return;
156 sigs = 0;
157
158#ifdef S_WINCH
159 if (tsignals & S_WINCH)
160 {
161 int old_width, old_height;
162 /*
163 * Re-execute get_term() to read the new window size.
164 */
165 old_width = sc_width;
166 old_height = sc_height;
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 (void)signal(SIGTTOU, SIG_IGN);
183#endif
184 lower_left();
185 clear_eol();
186 deinit();
187 (void)flush();
188 raw_mode(0);
189#ifdef SIGTTOU
190 (void)signal(SIGTTOU, SIG_DFL);
191#endif
192 (void)signal(SIGTSTP, SIG_DFL);
193 (void)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 (void)signal(SIGTSTP, stop);
201 raw_mode(1);
202 init();
203 screen_trashed = 1;
204 }
205#endif
206}