Annotation of src/usr.bin/less/signal.c, Revision 1.4
1.1 etheisen 1: /*
1.4 ! millert 2: * Copyright (C) 1984-2002 Mark Nudelman
1.1 etheisen 3: *
1.4 ! millert 4: * You may distribute under the terms of either the GNU General Public
! 5: * License or the Less License, as specified in the README file.
1.1 etheisen 6: *
1.4 ! millert 7: * For more information about less, or for information on how to
! 8: * contact the author, see the README file.
1.1 etheisen 9: */
10:
11:
12: /*
13: * Routines dealing with signals.
14: *
15: * A signal usually merely causes a bit to be set in the "signals" word.
16: * At some convenient time, the mainline code checks to see if any
17: * signals need processing by calling psignal().
18: * If we happen to be reading from a file [in iread()] at the time
19: * the signal is received, we call intread to interrupt the iread.
20: */
21:
22: #include "less.h"
23: #include <signal.h>
24:
25: /*
26: * "sigs" contains bits indicating signals which need to be processed.
27: */
28: public int sigs;
29:
30: extern int sc_width, sc_height;
31: extern int screen_trashed;
32: extern int lnloop;
33: extern int linenums;
34: extern int wscroll;
35: extern int reading;
36:
37: /*
38: * Interrupt signal handler.
39: */
40: /* ARGSUSED*/
41: static RETSIGTYPE
42: u_interrupt(type)
43: int type;
44: {
45: #if OS2
1.4 ! millert 46: LSIGNAL(SIGINT, SIG_ACK);
1.1 etheisen 47: #endif
1.4 ! millert 48: LSIGNAL(SIGINT, u_interrupt);
1.1 etheisen 49: sigs |= S_INTERRUPT;
1.4 ! millert 50: #if MSDOS_COMPILER==DJGPPC
! 51: /*
! 52: * If a keyboard has been hit, it must be Ctrl-C
! 53: * (as opposed to Ctrl-Break), so consume it.
! 54: * (Otherwise, Less will beep when it sees Ctrl-C from keyboard.)
! 55: */
! 56: if (kbhit())
! 57: getkey();
! 58: #endif
1.1 etheisen 59: if (reading)
60: intread();
61: }
62:
63: #ifdef SIGTSTP
64: /*
65: * "Stop" (^Z) signal handler.
66: */
67: /* ARGSUSED*/
68: static RETSIGTYPE
69: stop(type)
70: int type;
71: {
1.4 ! millert 72: LSIGNAL(SIGTSTP, stop);
1.1 etheisen 73: sigs |= S_STOP;
74: if (reading)
75: intread();
76: }
77: #endif
78:
79: #ifdef SIGWINCH
80: /*
81: * "Window" change handler
82: */
83: /* ARGSUSED*/
84: public RETSIGTYPE
85: winch(type)
86: int type;
87: {
1.4 ! millert 88: LSIGNAL(SIGWINCH, winch);
1.1 etheisen 89: sigs |= S_WINCH;
90: if (reading)
91: intread();
92: }
93: #else
94: #ifdef SIGWIND
95: /*
96: * "Window" change handler
97: */
98: /* ARGSUSED*/
99: public RETSIGTYPE
100: winch(type)
101: int type;
102: {
1.4 ! millert 103: LSIGNAL(SIGWIND, winch);
1.1 etheisen 104: sigs |= S_WINCH;
105: if (reading)
106: intread();
107: }
108: #endif
109: #endif
110:
1.4 ! millert 111: #if MSDOS_COMPILER==WIN32C
! 112: /*
! 113: * Handle CTRL-C and CTRL-BREAK keys.
! 114: */
! 115: #include "windows.h"
! 116:
! 117: static BOOL WINAPI
! 118: wbreak_handler(dwCtrlType)
! 119: DWORD dwCtrlType;
! 120: {
! 121: switch (dwCtrlType)
! 122: {
! 123: case CTRL_C_EVENT:
! 124: case CTRL_BREAK_EVENT:
! 125: sigs |= S_INTERRUPT;
! 126: return (TRUE);
! 127: default:
! 128: break;
! 129: }
! 130: return (FALSE);
! 131: }
! 132: #endif
! 133:
1.1 etheisen 134: /*
135: * Set up the signal handlers.
136: */
137: public void
138: init_signals(on)
139: int on;
140: {
141: if (on)
142: {
143: /*
144: * Set signal handlers.
145: */
1.4 ! millert 146: (void) LSIGNAL(SIGINT, u_interrupt);
! 147: #if MSDOS_COMPILER==WIN32C
! 148: SetConsoleCtrlHandler(wbreak_handler, TRUE);
! 149: #endif
1.1 etheisen 150: #ifdef SIGTSTP
1.4 ! millert 151: (void) LSIGNAL(SIGTSTP, stop);
1.1 etheisen 152: #endif
153: #ifdef SIGWINCH
1.4 ! millert 154: (void) LSIGNAL(SIGWINCH, winch);
1.1 etheisen 155: #else
156: #ifdef SIGWIND
1.4 ! millert 157: (void) LSIGNAL(SIGWIND, winch);
! 158: #endif
! 159: #ifdef SIGQUIT
! 160: (void) LSIGNAL(SIGQUIT, SIG_IGN);
1.1 etheisen 161: #endif
162: #endif
163: } else
164: {
165: /*
166: * Restore signals to defaults.
167: */
1.4 ! millert 168: (void) LSIGNAL(SIGINT, SIG_DFL);
! 169: #if MSDOS_COMPILER==WIN32C
! 170: SetConsoleCtrlHandler(wbreak_handler, FALSE);
! 171: #endif
1.1 etheisen 172: #ifdef SIGTSTP
1.4 ! millert 173: (void) LSIGNAL(SIGTSTP, SIG_DFL);
1.1 etheisen 174: #endif
175: #ifdef SIGWINCH
1.4 ! millert 176: (void) LSIGNAL(SIGWINCH, SIG_IGN);
1.1 etheisen 177: #endif
178: #ifdef SIGWIND
1.4 ! millert 179: (void) LSIGNAL(SIGWIND, SIG_IGN);
! 180: #endif
! 181: #ifdef SIGQUIT
! 182: (void) LSIGNAL(SIGQUIT, SIG_DFL);
1.1 etheisen 183: #endif
184: }
185: }
186:
187: /*
188: * Process any signals we have received.
189: * A received signal cause a bit to be set in "sigs".
190: */
191: public void
192: psignals()
193: {
1.4 ! millert 194: register int tsignals;
1.1 etheisen 195:
196: if ((tsignals = sigs) == 0)
197: return;
198: sigs = 0;
199:
200: #ifdef SIGTSTP
201: if (tsignals & S_STOP)
202: {
203: /*
204: * Clean up the terminal.
205: */
206: #ifdef SIGTTOU
1.4 ! millert 207: LSIGNAL(SIGTTOU, SIG_IGN);
1.1 etheisen 208: #endif
209: clear_bot();
210: deinit();
211: flush();
212: raw_mode(0);
213: #ifdef SIGTTOU
1.4 ! millert 214: LSIGNAL(SIGTTOU, SIG_DFL);
1.1 etheisen 215: #endif
1.4 ! millert 216: LSIGNAL(SIGTSTP, SIG_DFL);
1.1 etheisen 217: kill(getpid(), SIGTSTP);
218: /*
219: * ... Bye bye. ...
220: * Hopefully we'll be back later and resume here...
221: * Reset the terminal and arrange to repaint the
222: * screen when we get back to the main command loop.
223: */
1.4 ! millert 224: LSIGNAL(SIGTSTP, stop);
1.1 etheisen 225: raw_mode(1);
226: init();
227: screen_trashed = 1;
228: tsignals |= S_WINCH;
229: }
230: #endif
231: #ifdef S_WINCH
232: if (tsignals & S_WINCH)
233: {
234: int old_width, old_height;
235: /*
236: * Re-execute scrsize() to read the new window size.
237: */
238: old_width = sc_width;
239: old_height = sc_height;
240: get_term();
241: if (sc_width != old_width || sc_height != old_height)
242: {
243: wscroll = (sc_height + 1) / 2;
244: screen_trashed = 1;
245: }
246: }
247: #endif
248: if (tsignals & S_INTERRUPT)
249: {
250: bell();
251: /*
252: * {{ You may wish to replace the bell() with
253: * error("Interrupt", NULL_PARG); }}
254: */
255:
256: /*
257: * If we were interrupted while in the "calculating
258: * line numbers" loop, turn off line numbers.
259: */
260: if (lnloop)
261: {
262: lnloop = 0;
263: if (linenums == 2)
264: screen_trashed = 1;
265: linenums = 0;
266: error("Line numbers turned off", NULL_PARG);
267: }
268:
269: }
270: }