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