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