Annotation of src/usr.bin/less/signal.c, Revision 1.1.1.3
1.1 etheisen 1: /*
1.1.1.3 ! shadchin 2: * Copyright (C) 1984-2011 Mark Nudelman
1.1 etheisen 3: *
1.1.1.2 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.1.1.2 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;
1.1.1.3 ! shadchin 36: extern int quit_on_intr;
! 37: extern long jump_sline_fraction;
1.1 etheisen 38:
39: /*
40: * Interrupt signal handler.
41: */
42: /* ARGSUSED*/
43: static RETSIGTYPE
44: u_interrupt(type)
45: int type;
46: {
1.1.1.3 ! shadchin 47: bell();
1.1 etheisen 48: #if OS2
1.1.1.2 millert 49: LSIGNAL(SIGINT, SIG_ACK);
1.1 etheisen 50: #endif
1.1.1.2 millert 51: LSIGNAL(SIGINT, u_interrupt);
1.1 etheisen 52: sigs |= S_INTERRUPT;
1.1.1.2 millert 53: #if MSDOS_COMPILER==DJGPPC
54: /*
55: * If a keyboard has been hit, it must be Ctrl-C
56: * (as opposed to Ctrl-Break), so consume it.
57: * (Otherwise, Less will beep when it sees Ctrl-C from keyboard.)
58: */
59: if (kbhit())
60: getkey();
61: #endif
1.1 etheisen 62: if (reading)
1.1.1.3 ! shadchin 63: intread(); /* May longjmp */
1.1 etheisen 64: }
65:
66: #ifdef SIGTSTP
67: /*
68: * "Stop" (^Z) signal handler.
69: */
70: /* ARGSUSED*/
71: static RETSIGTYPE
72: stop(type)
73: int type;
74: {
1.1.1.2 millert 75: LSIGNAL(SIGTSTP, stop);
1.1 etheisen 76: sigs |= S_STOP;
77: if (reading)
78: intread();
79: }
80: #endif
81:
82: #ifdef SIGWINCH
83: /*
84: * "Window" change handler
85: */
86: /* ARGSUSED*/
87: public RETSIGTYPE
88: winch(type)
89: int type;
90: {
1.1.1.2 millert 91: LSIGNAL(SIGWINCH, winch);
1.1 etheisen 92: sigs |= S_WINCH;
93: if (reading)
94: intread();
95: }
96: #else
97: #ifdef SIGWIND
98: /*
99: * "Window" change handler
100: */
101: /* ARGSUSED*/
102: public RETSIGTYPE
103: winch(type)
104: int type;
105: {
1.1.1.2 millert 106: LSIGNAL(SIGWIND, winch);
1.1 etheisen 107: sigs |= S_WINCH;
108: if (reading)
109: intread();
110: }
111: #endif
112: #endif
113:
1.1.1.2 millert 114: #if MSDOS_COMPILER==WIN32C
115: /*
116: * Handle CTRL-C and CTRL-BREAK keys.
117: */
118: #include "windows.h"
119:
120: static BOOL WINAPI
121: wbreak_handler(dwCtrlType)
122: DWORD dwCtrlType;
123: {
124: switch (dwCtrlType)
125: {
126: case CTRL_C_EVENT:
127: case CTRL_BREAK_EVENT:
128: sigs |= S_INTERRUPT;
129: return (TRUE);
130: default:
131: break;
132: }
133: return (FALSE);
134: }
135: #endif
136:
1.1 etheisen 137: /*
138: * Set up the signal handlers.
139: */
140: public void
141: init_signals(on)
142: int on;
143: {
144: if (on)
145: {
146: /*
147: * Set signal handlers.
148: */
1.1.1.2 millert 149: (void) LSIGNAL(SIGINT, u_interrupt);
150: #if MSDOS_COMPILER==WIN32C
151: SetConsoleCtrlHandler(wbreak_handler, TRUE);
152: #endif
1.1 etheisen 153: #ifdef SIGTSTP
1.1.1.2 millert 154: (void) LSIGNAL(SIGTSTP, stop);
1.1 etheisen 155: #endif
156: #ifdef SIGWINCH
1.1.1.2 millert 157: (void) LSIGNAL(SIGWINCH, winch);
1.1.1.3 ! shadchin 158: #endif
1.1 etheisen 159: #ifdef SIGWIND
1.1.1.2 millert 160: (void) LSIGNAL(SIGWIND, winch);
161: #endif
162: #ifdef SIGQUIT
163: (void) LSIGNAL(SIGQUIT, SIG_IGN);
1.1 etheisen 164: #endif
165: } else
166: {
167: /*
168: * Restore signals to defaults.
169: */
1.1.1.2 millert 170: (void) LSIGNAL(SIGINT, SIG_DFL);
171: #if MSDOS_COMPILER==WIN32C
172: SetConsoleCtrlHandler(wbreak_handler, FALSE);
173: #endif
1.1 etheisen 174: #ifdef SIGTSTP
1.1.1.2 millert 175: (void) LSIGNAL(SIGTSTP, SIG_DFL);
1.1 etheisen 176: #endif
177: #ifdef SIGWINCH
1.1.1.2 millert 178: (void) LSIGNAL(SIGWINCH, SIG_IGN);
1.1 etheisen 179: #endif
180: #ifdef SIGWIND
1.1.1.2 millert 181: (void) LSIGNAL(SIGWIND, SIG_IGN);
182: #endif
183: #ifdef SIGQUIT
184: (void) LSIGNAL(SIGQUIT, SIG_DFL);
1.1 etheisen 185: #endif
186: }
187: }
188:
189: /*
190: * Process any signals we have received.
191: * A received signal cause a bit to be set in "sigs".
192: */
193: public void
194: psignals()
195: {
196: register int tsignals;
197:
198: if ((tsignals = sigs) == 0)
199: return;
200: sigs = 0;
201:
202: #ifdef SIGTSTP
203: if (tsignals & S_STOP)
204: {
205: /*
206: * Clean up the terminal.
207: */
208: #ifdef SIGTTOU
1.1.1.2 millert 209: LSIGNAL(SIGTTOU, SIG_IGN);
1.1 etheisen 210: #endif
211: clear_bot();
212: deinit();
213: flush();
214: raw_mode(0);
215: #ifdef SIGTTOU
1.1.1.2 millert 216: LSIGNAL(SIGTTOU, SIG_DFL);
1.1 etheisen 217: #endif
1.1.1.2 millert 218: LSIGNAL(SIGTSTP, SIG_DFL);
1.1 etheisen 219: kill(getpid(), SIGTSTP);
220: /*
221: * ... Bye bye. ...
222: * Hopefully we'll be back later and resume here...
223: * Reset the terminal and arrange to repaint the
224: * screen when we get back to the main command loop.
225: */
1.1.1.2 millert 226: LSIGNAL(SIGTSTP, stop);
1.1 etheisen 227: raw_mode(1);
228: init();
229: screen_trashed = 1;
230: tsignals |= S_WINCH;
231: }
232: #endif
233: #ifdef S_WINCH
234: if (tsignals & S_WINCH)
235: {
236: int old_width, old_height;
237: /*
238: * Re-execute scrsize() to read the new window size.
239: */
240: old_width = sc_width;
241: old_height = sc_height;
242: get_term();
243: if (sc_width != old_width || sc_height != old_height)
244: {
245: wscroll = (sc_height + 1) / 2;
1.1.1.3 ! shadchin 246: calc_jump_sline();
! 247: calc_shift_count();
1.1 etheisen 248: screen_trashed = 1;
249: }
250: }
251: #endif
252: if (tsignals & S_INTERRUPT)
253: {
1.1.1.3 ! shadchin 254: if (quit_on_intr)
! 255: quit(QUIT_INTERRUPT);
1.1 etheisen 256: }
257: }