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