Import less-436.
[dragonfly.git] / contrib / less / signal.c
blobb5e29772fe8f6508b54c8c28dcb0a2fce7919ac9
1 /*
2 * Copyright (C) 1984-2009 Mark Nudelman
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.
7 * For more information about less, or for information on how to
8 * contact the author, see the README file.
9 */
13 * Routines dealing with signals.
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.
22 #include "less.h"
23 #include <signal.h>
26 * "sigs" contains bits indicating signals which need to be processed.
28 public int sigs;
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 extern int quit_on_intr;
37 extern long jump_sline_fraction;
40 * Interrupt signal handler.
42 /* ARGSUSED*/
43 static RETSIGTYPE
44 u_interrupt(type)
45 int type;
47 bell();
48 #if OS2
49 LSIGNAL(SIGINT, SIG_ACK);
50 #endif
51 LSIGNAL(SIGINT, u_interrupt);
52 sigs |= S_INTERRUPT;
53 #if MSDOS_COMPILER==DJGPPC
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.)
59 if (kbhit())
60 getkey();
61 #endif
62 if (reading)
63 intread(); /* May longjmp */
66 #ifdef SIGTSTP
68 * "Stop" (^Z) signal handler.
70 /* ARGSUSED*/
71 static RETSIGTYPE
72 stop(type)
73 int type;
75 LSIGNAL(SIGTSTP, stop);
76 sigs |= S_STOP;
77 if (reading)
78 intread();
80 #endif
82 #ifdef SIGWINCH
84 * "Window" change handler
86 /* ARGSUSED*/
87 public RETSIGTYPE
88 winch(type)
89 int type;
91 LSIGNAL(SIGWINCH, winch);
92 sigs |= S_WINCH;
93 if (reading)
94 intread();
96 #else
97 #ifdef SIGWIND
99 * "Window" change handler
101 /* ARGSUSED*/
102 public RETSIGTYPE
103 winch(type)
104 int type;
106 LSIGNAL(SIGWIND, winch);
107 sigs |= S_WINCH;
108 if (reading)
109 intread();
111 #endif
112 #endif
114 #if MSDOS_COMPILER==WIN32C
116 * Handle CTRL-C and CTRL-BREAK keys.
118 #include "windows.h"
120 static BOOL WINAPI
121 wbreak_handler(dwCtrlType)
122 DWORD dwCtrlType;
124 switch (dwCtrlType)
126 case CTRL_C_EVENT:
127 case CTRL_BREAK_EVENT:
128 sigs |= S_INTERRUPT;
129 return (TRUE);
130 default:
131 break;
133 return (FALSE);
135 #endif
138 * Set up the signal handlers.
140 public void
141 init_signals(on)
142 int on;
144 if (on)
147 * Set signal handlers.
149 (void) LSIGNAL(SIGINT, u_interrupt);
150 #if MSDOS_COMPILER==WIN32C
151 SetConsoleCtrlHandler(wbreak_handler, TRUE);
152 #endif
153 #ifdef SIGTSTP
154 (void) LSIGNAL(SIGTSTP, stop);
155 #endif
156 #ifdef SIGWINCH
157 (void) LSIGNAL(SIGWINCH, winch);
158 #endif
159 #ifdef SIGWIND
160 (void) LSIGNAL(SIGWIND, winch);
161 #endif
162 #ifdef SIGQUIT
163 (void) LSIGNAL(SIGQUIT, SIG_IGN);
164 #endif
165 } else
168 * Restore signals to defaults.
170 (void) LSIGNAL(SIGINT, SIG_DFL);
171 #if MSDOS_COMPILER==WIN32C
172 SetConsoleCtrlHandler(wbreak_handler, FALSE);
173 #endif
174 #ifdef SIGTSTP
175 (void) LSIGNAL(SIGTSTP, SIG_DFL);
176 #endif
177 #ifdef SIGWINCH
178 (void) LSIGNAL(SIGWINCH, SIG_IGN);
179 #endif
180 #ifdef SIGWIND
181 (void) LSIGNAL(SIGWIND, SIG_IGN);
182 #endif
183 #ifdef SIGQUIT
184 (void) LSIGNAL(SIGQUIT, SIG_DFL);
185 #endif
190 * Process any signals we have received.
191 * A received signal cause a bit to be set in "sigs".
193 public void
194 psignals()
196 register int tsignals;
198 if ((tsignals = sigs) == 0)
199 return;
200 sigs = 0;
202 #ifdef SIGTSTP
203 if (tsignals & S_STOP)
206 * Clean up the terminal.
208 #ifdef SIGTTOU
209 LSIGNAL(SIGTTOU, SIG_IGN);
210 #endif
211 clear_bot();
212 deinit();
213 flush();
214 raw_mode(0);
215 #ifdef SIGTTOU
216 LSIGNAL(SIGTTOU, SIG_DFL);
217 #endif
218 LSIGNAL(SIGTSTP, SIG_DFL);
219 kill(getpid(), SIGTSTP);
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.
226 LSIGNAL(SIGTSTP, stop);
227 raw_mode(1);
228 init();
229 screen_trashed = 1;
230 tsignals |= S_WINCH;
232 #endif
233 #ifdef S_WINCH
234 if (tsignals & S_WINCH)
236 int old_width, old_height;
238 * Re-execute scrsize() to read the new window size.
240 old_width = sc_width;
241 old_height = sc_height;
242 get_term();
243 if (sc_width != old_width || sc_height != old_height)
245 wscroll = (sc_height + 1) / 2;
246 calc_jump_sline();
247 calc_shift_count();
248 screen_trashed = 1;
251 #endif
252 if (tsignals & S_INTERRUPT)
254 if (quit_on_intr)
255 quit(QUIT_OK);