Disconnect hostapd from building in base
[dragonfly.git] / contrib / less / signal.c
1 /*
2  * Copyright (C) 1984-2014  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, see the README file.
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  * If we happen to be reading from a file [in iread()] at the time
18  * the signal is received, we call intread to interrupt the iread.
19  */
20
21 #include "less.h"
22 #include <signal.h>
23
24 /*
25  * "sigs" contains bits indicating signals which need to be processed.
26  */
27 public int sigs;
28
29 extern int sc_width, sc_height;
30 extern int screen_trashed;
31 extern int lnloop;
32 extern int linenums;
33 extern int wscroll;
34 extern int reading;
35 extern int quit_on_intr;
36 extern long jump_sline_fraction;
37
38 /*
39  * Interrupt signal handler.
40  */
41         /* ARGSUSED*/
42         static RETSIGTYPE
43 u_interrupt(type)
44         int type;
45 {
46         bell();
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 (reading)
62                 intread(); /* May longjmp */
63 }
64
65 #ifdef SIGTSTP
66 /*
67  * "Stop" (^Z) signal handler.
68  */
69         /* ARGSUSED*/
70         static RETSIGTYPE
71 stop(type)
72         int type;
73 {
74         LSIGNAL(SIGTSTP, stop);
75         sigs |= S_STOP;
76         if (reading)
77                 intread();
78 }
79 #endif
80
81 #ifdef SIGWINCH
82 /*
83  * "Window" change handler
84  */
85         /* ARGSUSED*/
86         public RETSIGTYPE
87 winch(type)
88         int type;
89 {
90         LSIGNAL(SIGWINCH, winch);
91         sigs |= S_WINCH;
92         if (reading)
93                 intread();
94 }
95 #else
96 #ifdef SIGWIND
97 /*
98  * "Window" change handler
99  */
100         /* ARGSUSED*/
101         public RETSIGTYPE
102 winch(type)
103         int type;
104 {
105         LSIGNAL(SIGWIND, winch);
106         sigs |= S_WINCH;
107         if (reading)
108                 intread();
109 }
110 #endif
111 #endif
112
113 #if MSDOS_COMPILER==WIN32C
114 /*
115  * Handle CTRL-C and CTRL-BREAK keys.
116  */
117 #include "windows.h"
118
119         static BOOL WINAPI 
120 wbreak_handler(dwCtrlType)
121         DWORD dwCtrlType;
122 {
123         switch (dwCtrlType)
124         {
125         case CTRL_C_EVENT:
126         case CTRL_BREAK_EVENT:
127                 sigs |= S_INTERRUPT;
128                 return (TRUE);
129         default:
130                 break;
131         }
132         return (FALSE);
133 }
134 #endif
135
136 /*
137  * Set up the signal handlers.
138  */
139         public void
140 init_signals(on)
141         int on;
142 {
143         if (on)
144         {
145                 /*
146                  * Set signal handlers.
147                  */
148                 (void) LSIGNAL(SIGINT, u_interrupt);
149 #if MSDOS_COMPILER==WIN32C
150                 SetConsoleCtrlHandler(wbreak_handler, TRUE);
151 #endif
152 #ifdef SIGTSTP
153                 (void) LSIGNAL(SIGTSTP, stop);
154 #endif
155 #ifdef SIGWINCH
156                 (void) LSIGNAL(SIGWINCH, winch);
157 #endif
158 #ifdef SIGWIND
159                 (void) LSIGNAL(SIGWIND, winch);
160 #endif
161 #ifdef SIGQUIT
162                 (void) LSIGNAL(SIGQUIT, SIG_IGN);
163 #endif
164         } else
165         {
166                 /*
167                  * Restore signals to defaults.
168                  */
169                 (void) LSIGNAL(SIGINT, SIG_DFL);
170 #if MSDOS_COMPILER==WIN32C
171                 SetConsoleCtrlHandler(wbreak_handler, FALSE);
172 #endif
173 #ifdef SIGTSTP
174                 (void) LSIGNAL(SIGTSTP, SIG_DFL);
175 #endif
176 #ifdef SIGWINCH
177                 (void) LSIGNAL(SIGWINCH, SIG_IGN);
178 #endif
179 #ifdef SIGWIND
180                 (void) LSIGNAL(SIGWIND, SIG_IGN);
181 #endif
182 #ifdef SIGQUIT
183                 (void) LSIGNAL(SIGQUIT, SIG_DFL);
184 #endif
185         }
186 }
187
188 /*
189  * Process any signals we have received.
190  * A received signal cause a bit to be set in "sigs".
191  */
192         public void
193 psignals()
194 {
195         register int tsignals;
196
197         if ((tsignals = sigs) == 0)
198                 return;
199         sigs = 0;
200
201 #ifdef SIGTSTP
202         if (tsignals & S_STOP)
203         {
204                 /*
205                  * Clean up the terminal.
206                  */
207 #ifdef SIGTTOU
208                 LSIGNAL(SIGTTOU, SIG_IGN);
209 #endif
210                 clear_bot();
211                 deinit();
212                 flush();
213                 raw_mode(0);
214 #ifdef SIGTTOU
215                 LSIGNAL(SIGTTOU, SIG_DFL);
216 #endif
217                 LSIGNAL(SIGTSTP, SIG_DFL);
218                 kill(getpid(), SIGTSTP);
219                 /*
220                  * ... Bye bye. ...
221                  * Hopefully we'll be back later and resume here...
222                  * Reset the terminal and arrange to repaint the
223                  * screen when we get back to the main command loop.
224                  */
225                 LSIGNAL(SIGTSTP, stop);
226                 raw_mode(1);
227                 init();
228                 screen_trashed = 1;
229                 tsignals |= S_WINCH;
230         }
231 #endif
232 #ifdef S_WINCH
233         if (tsignals & S_WINCH)
234         {
235                 int old_width, old_height;
236                 /*
237                  * Re-execute scrsize() to read the new window size.
238                  */
239                 old_width = sc_width;
240                 old_height = sc_height;
241                 get_term();
242                 if (sc_width != old_width || sc_height != old_height)
243                 {
244                         wscroll = (sc_height + 1) / 2;
245                         calc_jump_sline();
246                         calc_shift_count();
247                         screen_trashed = 1;
248                 }
249         }
250 #endif
251         if (tsignals & S_INTERRUPT)
252         {
253                 if (quit_on_intr)
254                         quit(QUIT_INTERRUPT);
255         }
256 }