etc/services - sync with NetBSD-8
[minix.git] / external / bsd / less / dist / signal.c
bloba37f776dfb505aca30511eaf5028f3ac79542e11
1 /* $NetBSD: signal.c,v 1.4 2013/09/04 19:44:21 tron Exp $ */
3 /*
4 * Copyright (C) 1984-2012 Mark Nudelman
6 * You may distribute under the terms of either the GNU General Public
7 * License or the Less License, as specified in the README file.
9 * For more information, see the README file.
14 * Routines dealing with signals.
16 * A signal usually merely causes a bit to be set in the "signals" word.
17 * At some convenient time, the mainline code checks to see if any
18 * signals need processing by calling psignal().
19 * If we happen to be reading from a file [in iread()] at the time
20 * the signal is received, we call intread to interrupt the iread.
23 #include "less.h"
24 #include <signal.h>
27 * "sigs" contains bits indicating signals which need to be processed.
29 public int sigs;
31 static RETSIGTYPE u_interrupt __P((int));
32 static RETSIGTYPE stop __P((int));
33 #if MSDOS_COMPILER==WIN32C
34 static BOOL WINAPI wbreak_handler __P((DWORD));
35 #endif
37 extern int sc_width, sc_height;
38 extern int screen_trashed;
39 extern int lnloop;
40 extern int linenums;
41 extern int wscroll;
42 extern int reading;
43 extern int quit_on_intr;
44 extern long jump_sline_fraction;
47 * Interrupt signal handler.
49 /* ARGSUSED*/
50 static RETSIGTYPE
51 u_interrupt(type)
52 int type;
54 bell();
55 #if OS2
56 LSIGNAL(SIGINT, SIG_ACK);
57 #endif
58 LSIGNAL(SIGINT, u_interrupt);
59 sigs |= S_INTERRUPT;
60 #if MSDOS_COMPILER==DJGPPC
62 * If a keyboard has been hit, it must be Ctrl-C
63 * (as opposed to Ctrl-Break), so consume it.
64 * (Otherwise, Less will beep when it sees Ctrl-C from keyboard.)
66 if (kbhit())
67 getkey();
68 #endif
69 if (reading)
70 intread(); /* May longjmp */
73 #ifdef SIGTSTP
75 * "Stop" (^Z) signal handler.
77 /* ARGSUSED*/
78 static RETSIGTYPE
79 stop(type)
80 int type;
82 LSIGNAL(SIGTSTP, stop);
83 sigs |= S_STOP;
84 if (reading)
85 intread();
87 #endif
89 #ifdef SIGWINCH
91 * "Window" change handler
93 /* ARGSUSED*/
94 public RETSIGTYPE
95 winch(type)
96 int type;
98 LSIGNAL(SIGWINCH, winch);
99 sigs |= S_WINCH;
100 if (reading)
101 intread();
103 #else
104 #ifdef SIGWIND
106 * "Window" change handler
108 /* ARGSUSED*/
109 public RETSIGTYPE
110 winch(type)
111 int type;
113 LSIGNAL(SIGWIND, winch);
114 sigs |= S_WINCH;
115 if (reading)
116 intread();
118 #endif
119 #endif
121 #if MSDOS_COMPILER==WIN32C
123 * Handle CTRL-C and CTRL-BREAK keys.
125 #include "windows.h"
127 static BOOL WINAPI
128 wbreak_handler(dwCtrlType)
129 DWORD dwCtrlType;
131 switch (dwCtrlType)
133 case CTRL_C_EVENT:
134 case CTRL_BREAK_EVENT:
135 sigs |= S_INTERRUPT;
136 return (TRUE);
137 default:
138 break;
140 return (FALSE);
142 #endif
145 * Set up the signal handlers.
147 public void
148 init_signals(on)
149 int on;
151 if (on)
154 * Set signal handlers.
156 (void) LSIGNAL(SIGINT, u_interrupt);
157 #if MSDOS_COMPILER==WIN32C
158 SetConsoleCtrlHandler(wbreak_handler, TRUE);
159 #endif
160 #ifdef SIGTSTP
161 (void) LSIGNAL(SIGTSTP, stop);
162 #endif
163 #ifdef SIGWINCH
164 (void) LSIGNAL(SIGWINCH, winch);
165 #endif
166 #ifdef SIGWIND
167 (void) LSIGNAL(SIGWIND, winch);
168 #endif
169 #ifdef SIGQUIT
170 (void) LSIGNAL(SIGQUIT, SIG_IGN);
171 #endif
172 } else
175 * Restore signals to defaults.
177 (void) LSIGNAL(SIGINT, SIG_DFL);
178 #if MSDOS_COMPILER==WIN32C
179 SetConsoleCtrlHandler(wbreak_handler, FALSE);
180 #endif
181 #ifdef SIGTSTP
182 (void) LSIGNAL(SIGTSTP, SIG_DFL);
183 #endif
184 #ifdef SIGWINCH
185 (void) LSIGNAL(SIGWINCH, SIG_IGN);
186 #endif
187 #ifdef SIGWIND
188 (void) LSIGNAL(SIGWIND, SIG_IGN);
189 #endif
190 #ifdef SIGQUIT
191 (void) LSIGNAL(SIGQUIT, SIG_DFL);
192 #endif
197 * Process any signals we have received.
198 * A received signal cause a bit to be set in "sigs".
200 public void
201 psignals()
203 register int tsignals;
205 if ((tsignals = sigs) == 0)
206 return;
207 sigs = 0;
209 #ifdef SIGTSTP
210 if (tsignals & S_STOP)
213 * Clean up the terminal.
215 #ifdef SIGTTOU
216 LSIGNAL(SIGTTOU, SIG_IGN);
217 #endif
218 clear_bot();
219 deinit();
220 flush();
221 raw_mode(0);
222 #ifdef SIGTTOU
223 LSIGNAL(SIGTTOU, SIG_DFL);
224 #endif
225 LSIGNAL(SIGTSTP, SIG_DFL);
226 kill(getpid(), SIGTSTP);
228 * ... Bye bye. ...
229 * Hopefully we'll be back later and resume here...
230 * Reset the terminal and arrange to repaint the
231 * screen when we get back to the main command loop.
233 LSIGNAL(SIGTSTP, stop);
234 raw_mode(1);
235 init();
236 screen_trashed = 1;
237 tsignals |= S_WINCH;
239 #endif
240 #ifdef S_WINCH
241 if (tsignals & S_WINCH)
243 int old_width, old_height;
245 * Re-execute scrsize() to read the new window size.
247 old_width = sc_width;
248 old_height = sc_height;
249 get_term();
250 if (sc_width != old_width || sc_height != old_height)
252 wscroll = (sc_height + 1) / 2;
253 calc_jump_sline();
254 calc_shift_count();
255 screen_trashed = 1;
258 #endif
259 if (tsignals & S_INTERRUPT)
261 if (quit_on_intr)
262 quit(QUIT_INTERRUPT);