xref: /original-bsd/usr.bin/more/signal.c (revision bdd86a84)
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
21 static char sccsid[] = "@(#)signal.c	5.4 (Berkeley) 07/25/88";
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  */
40 public int 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 
49 extern int sc_width, sc_height;
50 extern int screen_trashed;
51 extern int lnloop;
52 extern int linenums;
53 extern int scroll;
54 extern int reading;
55 
56 #ifdef SIGTSTP
57 /*
58  * "Stop" (^Z) signal handler.
59  */
60 	static HANDLER
61 stop()
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  */
74 	public HANDLER
75 winch()
76 {
77 	signal(SIGWINCH, winch);
78 	sigs |= S_WINCH;
79 	if (reading)
80 		intread();
81 }
82 #else
83 #ifdef SIGWIND
84 /*
85  * "Window" change handler
86  */
87 	public HANDLER
88 winch()
89 {
90 	signal(SIGWIND, winch);
91 	sigs |= S_WINCH;
92 	if (reading)
93 		intread();
94 }
95 #endif
96 #endif
97 
98 /*
99  * Set up the signal handlers.
100  */
101 	public void
102 init_signals(on)
103 	int on;
104 {
105 	if (on)
106 	{
107 		/*
108 		 * Set signal handlers.
109 		 */
110 		(void) signal(SIGINT, quit);
111 #ifdef SIGTSTP
112 		(void) signal(SIGTSTP, stop);
113 #endif
114 #ifdef SIGWINCH
115 		(void) signal(SIGWINCH, winch);
116 #else
117 #ifdef SIGWIND
118 		(void) signal(SIGWIND, winch);
119 #endif
120 #endif
121 	} else
122 	{
123 		/*
124 		 * Restore signals to defaults.
125 		 */
126 		(void) signal(SIGINT, SIG_DFL);
127 #ifdef SIGTSTP
128 		(void) signal(SIGTSTP, SIG_DFL);
129 #endif
130 #ifdef SIGWINCH
131 		(void) signal(SIGWINCH, SIG_IGN);
132 #endif
133 #ifdef SIGWIND
134 		(void) signal(SIGWIND, SIG_IGN);
135 #endif
136 	}
137 }
138 
139 /*
140  * Process any signals we have received.
141  * A received signal cause a bit to be set in "sigs".
142  */
143 	public int
144 psignals()
145 {
146 	register int tsignals;
147 
148 	if ((tsignals = sigs) == 0)
149 		return;
150 	sigs = 0;
151 
152 #ifdef S_WINCH
153 	if (tsignals & S_WINCH)
154 	{
155 		int old_width, old_height;
156 		/*
157 		 * Re-execute get_term() to read the new window size.
158 		 */
159 		old_width = sc_width;
160 		old_height = sc_height;
161 		get_term();
162 		if (sc_width != old_width || sc_height != old_height)
163 		{
164 			scroll = (sc_height + 1) / 2;
165 			screen_trashed = 1;
166 		}
167 	}
168 #endif
169 #ifdef SIGTSTP
170 	if (tsignals & S_STOP)
171 	{
172 		/*
173 		 * Clean up the terminal.
174 		 */
175 #ifdef SIGTTOU
176 		signal(SIGTTOU, SIG_IGN);
177 #endif
178 		lower_left();
179 		clear_eol();
180 		deinit();
181 		flush();
182 		raw_mode(0);
183 #ifdef SIGTTOU
184 		signal(SIGTTOU, SIG_DFL);
185 #endif
186 		signal(SIGTSTP, SIG_DFL);
187 		kill(getpid(), SIGTSTP);
188 		/*
189 		 * ... Bye bye. ...
190 		 * Hopefully we'll be back later and resume here...
191 		 * Reset the terminal and arrange to repaint the
192 		 * screen when we get back to the main command loop.
193 		 */
194 		signal(SIGTSTP, stop);
195 		raw_mode(1);
196 		init();
197 		screen_trashed = 1;
198 	}
199 #endif
200 }
201