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