]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/less/signal.c
Optionally bind ktls threads to NUMA domains
[FreeBSD/FreeBSD.git] / contrib / less / signal.c
1 /*
2  * Copyright (C) 1984-2020  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 /* $FreeBSD$ */
11
12 /*
13  * Routines dealing with signals.
14  *
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.
20  */
21
22 #include "less.h"
23 #include <signal.h>
24
25 /*
26  * "sigs" contains bits indicating signals which need to be processed.
27  */
28 public int sigs;
29
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 int less_is_more;
38 extern long jump_sline_fraction;
39
40 /*
41  * Interrupt signal handler.
42  */
43 #if MSDOS_COMPILER!=WIN32C
44         /* ARGSUSED*/
45         static RETSIGTYPE
46 u_interrupt(type)
47         int type;
48 {
49         bell();
50 #if OS2
51         LSIGNAL(SIGINT, SIG_ACK);
52 #endif
53         LSIGNAL(SIGINT, u_interrupt);
54         sigs |= S_INTERRUPT;
55 #if MSDOS_COMPILER==DJGPPC
56         /*
57          * If a keyboard has been hit, it must be Ctrl-C
58          * (as opposed to Ctrl-Break), so consume it.
59          * (Otherwise, Less will beep when it sees Ctrl-C from keyboard.)
60          */
61         if (kbhit())
62                 getkey();
63 #endif
64         if (less_is_more)
65                 quit(0);
66         if (reading)
67                 intread(); /* May longjmp */
68 }
69 #endif
70
71 #ifdef SIGTSTP
72 /*
73  * "Stop" (^Z) signal handler.
74  */
75         /* ARGSUSED*/
76         static RETSIGTYPE
77 stop(type)
78         int type;
79 {
80         LSIGNAL(SIGTSTP, stop);
81         sigs |= S_STOP;
82         if (reading)
83                 intread();
84 }
85 #endif
86
87 #undef SIG_LESSWINDOW
88 #ifdef SIGWINCH
89 #define SIG_LESSWINDOW SIGWINCH
90 #else
91 #ifdef SIGWIND
92 #define SIG_LESSWINDOW SIGWIND
93 #endif
94 #endif
95
96 #ifdef SIG_LESSWINDOW
97 /*
98  * "Window" change handler
99  */
100         /* ARGSUSED*/
101         public RETSIGTYPE
102 winch(type)
103         int type;
104 {
105         LSIGNAL(SIG_LESSWINDOW, winch);
106         sigs |= S_WINCH;
107         if (reading)
108                 intread();
109 }
110 #endif
111
112 #if MSDOS_COMPILER==WIN32C
113 /*
114  * Handle CTRL-C and CTRL-BREAK keys.
115  */
116 #define WIN32_LEAN_AND_MEAN
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         static RETSIGTYPE
137 terminate(type)
138         int type;
139 {
140         quit(15);
141 }
142
143 /*
144  * Set up the signal handlers.
145  */
146         public void
147 init_signals(on)
148         int on;
149 {
150         if (on)
151         {
152                 /*
153                  * Set signal handlers.
154                  */
155 #if MSDOS_COMPILER==WIN32C
156                 SetConsoleCtrlHandler(wbreak_handler, TRUE);
157 #else
158                 (void) LSIGNAL(SIGINT, u_interrupt);
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 #ifdef SIGTERM
173                 (void) LSIGNAL(SIGTERM, terminate);
174 #endif
175         } else
176         {
177                 /*
178                  * Restore signals to defaults.
179                  */
180 #if MSDOS_COMPILER==WIN32C
181                 SetConsoleCtrlHandler(wbreak_handler, FALSE);
182 #else
183                 (void) LSIGNAL(SIGINT, SIG_DFL);
184 #endif
185 #ifdef SIGTSTP
186                 (void) LSIGNAL(SIGTSTP, SIG_DFL);
187 #endif
188 #ifdef SIGWINCH
189                 (void) LSIGNAL(SIGWINCH, SIG_IGN);
190 #endif
191 #ifdef SIGWIND
192                 (void) LSIGNAL(SIGWIND, SIG_IGN);
193 #endif
194 #ifdef SIGQUIT
195                 (void) LSIGNAL(SIGQUIT, SIG_DFL);
196 #endif
197 #ifdef SIGTERM
198                 (void) LSIGNAL(SIGTERM, SIG_DFL);
199 #endif
200         }
201 }
202
203 /*
204  * Process any signals we have received.
205  * A received signal cause a bit to be set in "sigs".
206  */
207         public void
208 psignals(VOID_PARAM)
209 {
210         int tsignals;
211
212         if ((tsignals = sigs) == 0)
213                 return;
214         sigs = 0;
215
216 #ifdef SIGTSTP
217         if (tsignals & S_STOP)
218         {
219                 /*
220                  * Clean up the terminal.
221                  */
222 #ifdef SIGTTOU
223                 LSIGNAL(SIGTTOU, SIG_IGN);
224 #endif
225                 clear_bot();
226                 deinit();
227                 flush();
228                 raw_mode(0);
229 #ifdef SIGTTOU
230                 LSIGNAL(SIGTTOU, SIG_DFL);
231 #endif
232                 LSIGNAL(SIGTSTP, SIG_DFL);
233                 kill(getpid(), SIGTSTP);
234                 /*
235                  * ... Bye bye. ...
236                  * Hopefully we'll be back later and resume here...
237                  * Reset the terminal and arrange to repaint the
238                  * screen when we get back to the main command loop.
239                  */
240                 LSIGNAL(SIGTSTP, stop);
241                 raw_mode(1);
242                 init();
243                 screen_trashed = 1;
244                 tsignals |= S_WINCH;
245         }
246 #endif
247 #ifdef S_WINCH
248         if (tsignals & S_WINCH)
249         {
250                 int old_width, old_height;
251                 /*
252                  * Re-execute scrsize() to read the new window size.
253                  */
254                 old_width = sc_width;
255                 old_height = sc_height;
256                 get_term();
257                 if (sc_width != old_width || sc_height != old_height)
258                 {
259                         wscroll = (sc_height + 1) / 2;
260                         calc_jump_sline();
261                         calc_shift_count();
262                 }
263                 screen_trashed = 1;
264         }
265 #endif
266         if (tsignals & S_INTERRUPT)
267         {
268                 if (quit_on_intr)
269                         quit(QUIT_INTERRUPT);
270         }
271 }