Mercurial > hg > xemacs-beta
annotate src/signal.c @ 5898:2aeaf9bc7175
Regenerate configure.
author | Stephen J. Turnbull <stephen@xemacs.org> |
---|---|
date | Tue, 05 May 2015 04:06:37 +0900 |
parents | 308d34e9f07d |
children |
rev | line source |
---|---|
428 | 1 /* Handling asynchronous signals. |
2 Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. | |
5038 | 3 Copyright (C) 1995, 1996, 2001, 2002, 2004, 2010 Ben Wing. |
428 | 4 |
5 This file is part of XEmacs. | |
6 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5038
diff
changeset
|
7 XEmacs is free software: you can redistribute it and/or modify it |
428 | 8 under the terms of the GNU General Public License as published by the |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5038
diff
changeset
|
9 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5038
diff
changeset
|
10 option) any later version. |
428 | 11 |
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5038
diff
changeset
|
18 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
428 | 19 |
20 /* Synched up with: Not synched with FSF. Split out of keyboard.c. */ | |
21 | |
22 #include <config.h> | |
23 #include "lisp.h" | |
24 | |
25 #include "console.h" | |
872 | 26 #include "device-impl.h" |
428 | 27 #include "events.h" /* for signal_fake_event() */ |
872 | 28 #include "frame-impl.h" |
593 | 29 #include "process.h" |
611 | 30 |
428 | 31 #include "sysdep.h" |
611 | 32 #include "sysfile.h" |
428 | 33 #include "syssignal.h" |
34 #include "systime.h" | |
35 | |
36 /* Set to 1 when a quit-check signal (either a SIGIO interrupt or | |
37 the asynch. timeout for poll-for-quit) occurs. The QUITP | |
38 macro may look at this. */ | |
39 volatile int quit_check_signal_happened; | |
40 | |
41 /* Count of the number of times a quit-check signal has occurred. | |
42 Some stuff in event-Xt.c looks at this. */ | |
43 volatile int quit_check_signal_tick_count; | |
44 | |
45 /* Set to 1 when a SIGINT (or SIGQUIT) interrupt is processed. | |
46 maybe_read_quit_event() looks at this. */ | |
47 volatile int sigint_happened; | |
48 | |
49 /* Set to 1 when an asynch. timeout signal occurs. */ | |
593 | 50 static volatile int async_timeout_happened; |
51 | |
52 /* Set to 1 when a multiple of SLOWED_DOWN_INTERRUPTS_SECS elapses, | |
53 after slow_down_interrupts() is called. */ | |
54 static volatile int slowed_interrupt_timeout_happened; | |
428 | 55 |
56 /* This is used to synchronize setting the waiting_for_user_input_p | |
57 flag. */ | |
593 | 58 static volatile int async_timeout_happened_while_emacs_was_blocking; |
428 | 59 |
60 /* See check_quit() for when this is set. */ | |
61 int dont_check_for_quit; | |
62 | |
593 | 63 static int poll_for_quit_id; |
64 static int poll_for_sigchld_id; | |
428 | 65 |
66 /* This variable is used to communicate to a lisp | |
67 process-filter/sentinel/asynchronous callback (via the function | |
68 Fwaiting_for_user_input_p below) whether XEmacs was waiting for | |
69 user-input when that process-filter was called. */ | |
70 static int waiting_for_user_input_p; | |
71 | |
72 static int interrupts_slowed_down; | |
73 | |
74 #define SLOWED_DOWN_INTERRUPTS_SECS 15 | |
75 #define NORMAL_QUIT_CHECK_TIMEOUT_MSECS 250 | |
76 #define NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS 250 | |
77 | |
78 /* Used so that signals can break out of system calls that aren't | |
79 naturally interruptible. */ | |
80 | |
81 JMP_BUF break_system_call_jump; | |
82 volatile int can_break_system_calls; | |
83 | |
593 | 84 static SIGTYPE alarm_signal (int signo); |
85 | |
86 | |
428 | 87 |
88 /**********************************************************************/ | |
89 /* Asynchronous timeout functions */ | |
90 /**********************************************************************/ | |
91 | |
593 | 92 /* See the comment in event-stream.c, under major heading "Timeouts", |
93 for the difference between low-level (one-shot) and high-level | |
94 (periodic/resignaling) timeouts. */ | |
95 | |
428 | 96 /* The pending timers are stored in an ordered list, where the first timer |
97 on the list is the first one to fire. Times recorded here are | |
98 absolute. */ | |
99 static struct low_level_timeout *async_timer_queue; | |
100 | |
101 /* Nonzero means async timers are temporarily suppressed. */ | |
102 static int async_timer_suppress_count; | |
103 | |
104 static void | |
105 set_one_shot_timer (EMACS_TIME interval) | |
106 { | |
107 #ifdef HAVE_SETITIMER | |
108 struct itimerval it; | |
109 it.it_value = interval; | |
110 EMACS_SET_SECS_USECS (it.it_interval, 0, 0); | |
611 | 111 qxe_setitimer (ITIMER_REAL, &it, 0); |
428 | 112 #else |
113 int secs; | |
114 EMACS_TIME_TO_INT (interval, secs); | |
115 alarm (secs); | |
116 #endif | |
117 } | |
118 | |
119 static void | |
120 reset_interval_timer (void) | |
121 { | |
122 EMACS_TIME interval; | |
123 | |
124 /* Get the interval to set. If an interval is available, | |
125 make sure it's not zero (this is a valid return, but it will | |
126 cause the timer to get disabled, so convert it to a very short | |
127 time). */ | |
128 if (get_low_level_timeout_interval (async_timer_queue, &interval)) | |
129 { | |
130 if (EMACS_SECS (interval) == 0 && EMACS_USECS (interval) == 0) | |
131 EMACS_SET_USECS (interval, 1); | |
132 } | |
133 else | |
134 /* A time of 0 means "disable". */ | |
135 EMACS_SET_SECS_USECS (interval, 0, 0); | |
136 | |
137 set_one_shot_timer (interval); | |
138 } | |
139 | |
140 | |
141 static void | |
142 init_async_timeouts (void) | |
143 { | |
613 | 144 set_timeout_signal (SIGALRM, alarm_signal); |
428 | 145 async_timer_suppress_count = 0; |
146 } | |
147 | |
148 /* Turn off async timeouts. */ | |
149 | |
150 static void | |
151 stop_async_timeouts (void) | |
152 { | |
153 if (async_timer_suppress_count == 0) | |
154 { | |
155 /* If timer was on, turn it off. */ | |
156 EMACS_TIME thyme; | |
157 EMACS_SET_SECS_USECS (thyme, 0, 0); | |
158 set_one_shot_timer (thyme); | |
159 } | |
160 async_timer_suppress_count++; | |
161 } | |
162 | |
163 /* Turn on async timeouts again. */ | |
164 | |
165 static void | |
166 start_async_timeouts (void) | |
167 { | |
168 assert (async_timer_suppress_count > 0); | |
169 async_timer_suppress_count--; | |
170 if (async_timer_suppress_count == 0) | |
171 { | |
172 /* Some callers turn off async timeouts and then use the alarm | |
173 for their own purposes; so reinitialize everything. */ | |
613 | 174 set_timeout_signal (SIGALRM, alarm_signal); |
428 | 175 reset_interval_timer (); |
176 } | |
177 } | |
178 | |
593 | 179 static void |
180 handle_async_timeout_signal (void) | |
428 | 181 { |
593 | 182 int interval_id; |
183 int wakeup_id; | |
184 Lisp_Object fun, arg; | |
771 | 185 /* Avoid any possibility of GC during QUIT */ |
186 int specco = begin_gc_forbidden (); | |
593 | 187 |
188 /* No checks for Vinhibit_quit here or anywhere else in this file!!! | |
189 Otherwise critical quit will not work right. | |
771 | 190 The only check for Vinhibit_quit is in QUIT itself. |
191 | |
192 (#### ???? I don't quite understand this comment.) */ | |
593 | 193 interval_id = pop_low_level_timeout (&async_timer_queue, 0); |
194 | |
195 reset_interval_timer (); | |
196 if (async_timeout_happened_while_emacs_was_blocking) | |
197 { | |
198 async_timeout_happened_while_emacs_was_blocking = 0; | |
199 waiting_for_user_input_p = 1; | |
200 } | |
201 | |
202 wakeup_id = event_stream_resignal_wakeup (interval_id, 1, &fun, &arg); | |
428 | 203 |
593 | 204 if (wakeup_id == poll_for_quit_id) |
205 { | |
206 quit_check_signal_happened = 1; | |
207 quit_check_signal_tick_count++; | |
208 } | |
209 else if (wakeup_id == poll_for_sigchld_id) | |
428 | 210 { |
593 | 211 kick_status_notify (); |
428 | 212 } |
593 | 213 else |
214 /* call1 GC-protects its arguments */ | |
853 | 215 call1_trapping_problems ("Error in asynchronous timeout callback", |
216 fun, arg, INHIBIT_GC); | |
593 | 217 |
218 waiting_for_user_input_p = 0; | |
771 | 219 |
220 unbind_to (specco); | |
593 | 221 } |
222 | |
223 /* The following two functions are the external interface onto | |
224 creating/deleting asynchronous interval timeouts, and are | |
225 called by event-stream.c. We call back to event-stream.c using | |
226 event_stream_resignal_wakeup(), when an interval goes off. */ | |
227 | |
228 int | |
229 signal_add_async_interval_timeout (EMACS_TIME thyme) | |
230 { | |
231 int id = add_low_level_timeout (&async_timer_queue, thyme); | |
232 | |
233 /* If this timeout is at the head of the queue, then we need to | |
234 set the timer right now for this timeout. Otherwise, things | |
235 are fine as-is; after the timers ahead of us are signalled, | |
236 the timer will be set for us. */ | |
237 | |
238 if (async_timer_queue->id == id) | |
239 reset_interval_timer (); | |
240 | |
241 return id; | |
428 | 242 } |
243 | |
244 void | |
593 | 245 signal_remove_async_interval_timeout (int id) |
428 | 246 { |
593 | 247 int first = (async_timer_queue && async_timer_queue->id == id); |
248 remove_low_level_timeout (&async_timer_queue, id); | |
249 | |
250 /* If we removed the timeout from the head of the queue, then | |
251 we need to reset the interval timer right now. */ | |
252 if (first) | |
253 reset_interval_timer (); | |
428 | 254 } |
255 | |
593 | 256 /* If alarm() gets called when polling isn't disabled, it will mess up |
257 the asynchronous timeouts, and then C-g checking won't work again. | |
258 Some libraries call alarm() directly, so we override the standard | |
2500 | 259 library's alarm() and ABORT() if the caller of the library function |
593 | 260 didn't wrap in stop_interrupts()/start_interrupts(). |
428 | 261 |
593 | 262 NOTE: We could potentially avoid the need to wrap by adding a |
263 one-shot timeout to simulate the alarm(), smashing our signal | |
264 handler back into place, and calling the library function when the | |
265 alarm goes off. But do we want to? We're not going to gain the | |
266 ability to C-g out of library functions this way (unless we forcibly | |
267 longjmp() out of a signal handler, which is likely to lead to a | |
268 crash). --ben */ | |
428 | 269 |
270 #ifdef HAVE_SETITIMER | |
611 | 271 |
428 | 272 unsigned int |
273 alarm (unsigned int howlong) | |
274 { | |
275 struct itimerval old_it, new_it; | |
276 | |
277 assert (async_timer_suppress_count > 0); | |
278 | |
279 new_it.it_value.tv_sec = howlong; | |
280 new_it.it_value.tv_usec = 0; | |
281 new_it.it_interval.tv_sec = 0; | |
282 new_it.it_interval.tv_usec = 0; | |
611 | 283 qxe_setitimer (ITIMER_REAL, &new_it, &old_it); |
428 | 284 |
285 /* Never return zero if there was a timer outstanding. */ | |
286 return old_it.it_value.tv_sec + (old_it.it_value.tv_usec > 0 ? 1 : 0); | |
287 } | |
611 | 288 |
289 int | |
290 qxe_setitimer (int kind, const struct itimerval *itnew, | |
291 struct itimerval *itold) | |
292 { | |
1315 | 293 #ifdef WIN32_ANY |
611 | 294 /* setitimer() does not exist on native MS Windows, and appears broken |
617 | 295 on Cygwin. See win32.c. |
296 | |
297 We are emulating the Unix98 setitimer() function, as found in its | |
298 incarnations on modern versions of Unix. Note however that in | |
299 the win32.c version, ITNEW and ITOLD must be equal if both are | |
300 non-zero, due to limitations in the underlying multimedia-timer | |
301 API. */ | |
611 | 302 return mswindows_setitimer (kind, itnew, itold); |
303 #else | |
617 | 304 /* YUCK! glibc defines setitimer's first argument as |
305 enum __itimer_which, not int, which causes compile errors if | |
306 we call setitimer() in the obvious way. */ | |
307 switch (kind) | |
308 { | |
309 case ITIMER_REAL: return setitimer (ITIMER_REAL, itnew, itold); | |
310 case ITIMER_VIRTUAL: return setitimer (ITIMER_VIRTUAL, itnew, itold); | |
311 case ITIMER_PROF: return setitimer (ITIMER_PROF, itnew, itold); | |
2500 | 312 default: ABORT (); return 0; |
617 | 313 } |
428 | 314 #endif |
611 | 315 } |
316 | |
317 #endif /* HAVE_SETITIMER */ | |
318 | |
613 | 319 signal_handler_t |
320 set_timeout_signal (int signal_number, signal_handler_t action) | |
321 { | |
322 #ifdef CYGWIN_BROKEN_SIGNALS | |
323 return mswindows_sigset (signal_number, action); | |
324 #else | |
325 return EMACS_SIGNAL (signal_number, action); | |
326 #endif | |
327 } | |
428 | 328 |
329 DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, 0, 0, 0, /* | |
330 Return non-nil if XEmacs is waiting for input from the user. | |
331 This is intended for use by asynchronous timeout callbacks and by | |
332 asynchronous process output filters and sentinels (not yet implemented | |
333 in XEmacs). It will always be nil if XEmacs is not inside of | |
334 an asynchronous timeout or process callback. | |
335 */ | |
336 ()) | |
337 { | |
338 return waiting_for_user_input_p ? Qt : Qnil; | |
339 } | |
340 | |
341 | |
342 /**********************************************************************/ | |
593 | 343 /* Enabling/disabling signals */ |
344 /**********************************************************************/ | |
345 | |
346 static int interrupts_initted; | |
347 | |
348 void | |
349 stop_interrupts (void) | |
350 { | |
351 if (!interrupts_initted) | |
352 return; | |
353 #if defined(SIGIO) && !defined(BROKEN_SIGIO) | |
354 unrequest_sigio (); | |
355 #endif | |
356 stop_async_timeouts (); | |
357 } | |
358 | |
359 void | |
360 start_interrupts (void) | |
361 { | |
362 if (!interrupts_initted) | |
363 return; | |
364 #if defined(SIGIO) && !defined(BROKEN_SIGIO) | |
365 request_sigio (); | |
366 #endif | |
367 start_async_timeouts (); | |
368 } | |
369 | |
370 | |
371 static void | |
372 establish_slow_interrupt_timer (void) | |
373 { | |
374 EMACS_TIME thyme; | |
375 | |
376 EMACS_SET_SECS_USECS (thyme, SLOWED_DOWN_INTERRUPTS_SECS, 0); | |
377 set_one_shot_timer (thyme); | |
378 } | |
379 | |
380 /* Some functions don't like being interrupted with SIGALRM or SIGIO. | |
381 Previously we were calling stop_interrupts() / start_interrupts(), | |
382 but then if the program hangs in one of those functions, e.g. | |
383 waiting for a connect(), we're really screwed. So instead we | |
384 just "slow them down". We do this by disabling all interrupts | |
385 and then installing a timer of length fairly large, like 5 or | |
386 10 secs. That way, any "legitimate" connections (which should | |
387 take a fairly short amount of time) go through OK, but we can | |
388 interrupt bogus ones. */ | |
389 | |
390 void | |
391 slow_down_interrupts (void) | |
392 { | |
393 /* We have to set the flag *before* setting the slowed-down timer, | |
394 to avoid a race condition -- if the signal occurs between the | |
395 call to set_one_shot_timer() and the setting of this flag, | |
396 async_timeout_happened will get set, which will be a Bad Thing if | |
397 there were no timeouts on the queue. */ | |
398 interrupts_slowed_down++; | |
399 if (interrupts_slowed_down == 1) | |
400 { | |
401 stop_interrupts (); | |
402 establish_slow_interrupt_timer (); | |
403 } | |
404 } | |
405 | |
406 void | |
407 speed_up_interrupts (void) | |
408 { | |
409 if (interrupts_slowed_down > 0) | |
410 { | |
411 start_interrupts (); | |
412 /* Change this flag AFTER fiddling with interrupts, for the same | |
413 race-condition reasons as above. */ | |
414 interrupts_slowed_down--; | |
415 } | |
416 } | |
417 | |
418 | |
419 /**********************************************************************/ | |
420 /* The mechanism that drives it all */ | |
428 | 421 /**********************************************************************/ |
422 | |
593 | 423 /* called from QUIT when something_happened gets set (as a result of |
424 a signal) */ | |
425 | |
853 | 426 void |
593 | 427 check_what_happened (void) |
428 { | |
771 | 429 /* No GC can happen anywhere here. handle_async_timeout_signal() |
430 prevents GC (from asynch timeout handler), so does check_quit() | |
431 (from processing a message such as WM_INITMENU as a result of | |
432 draining the message queue). establish_slow_interrupt_timer() is | |
433 too low-level to do anything that might invoke QUIT or call Lisp | |
434 code. */ | |
1318 | 435 |
436 #ifdef ERROR_CHECK_TRAPPING_PROBLEMS | |
437 /* When in a critical section, don't reset something_happened, so that | |
438 every single QUIT will verify proper wrapping. (something_happened | |
439 was set by enter_redisplay_critical_section() and will be reset | |
440 upon exit.) */ | |
441 if (!in_display) | |
442 #endif | |
443 something_happened = 0; | |
444 | |
5014
c2e0c3af5fe3
cleanups to debug-print, try harder to make it work during GC
Ben Wing <ben@xemacs.org>
parents:
2518
diff
changeset
|
445 /* Don't try to do anything clever if we're called from debug_print() |
c2e0c3af5fe3
cleanups to debug-print, try harder to make it work during GC
Ben Wing <ben@xemacs.org>
parents:
2518
diff
changeset
|
446 or very close to startup or shutdown. */ |
c2e0c3af5fe3
cleanups to debug-print, try harder to make it work during GC
Ben Wing <ben@xemacs.org>
parents:
2518
diff
changeset
|
447 if (inhibit_non_essential_conversion_operations) |
c2e0c3af5fe3
cleanups to debug-print, try harder to make it work during GC
Ben Wing <ben@xemacs.org>
parents:
2518
diff
changeset
|
448 return; |
c2e0c3af5fe3
cleanups to debug-print, try harder to make it work during GC
Ben Wing <ben@xemacs.org>
parents:
2518
diff
changeset
|
449 |
593 | 450 if (async_timeout_happened) |
451 { | |
452 async_timeout_happened = 0; | |
453 handle_async_timeout_signal (); | |
454 } | |
455 if (slowed_interrupt_timeout_happened) | |
456 { | |
457 slowed_interrupt_timeout_happened = 0; | |
458 establish_slow_interrupt_timer (); | |
459 } | |
460 | |
853 | 461 check_quit (); |
593 | 462 } |
463 | |
464 #ifdef SIGIO | |
465 | |
466 /* Signal handler for SIGIO. */ | |
467 | |
468 static void | |
2286 | 469 input_available_signal (int SIG_ARG_MAYBE_UNUSED (signo)) |
593 | 470 { |
471 something_happened = 1; /* tell QUIT to wake up */ | |
472 quit_check_signal_happened = 1; | |
473 quit_check_signal_tick_count++; | |
474 EMACS_REESTABLISH_SIGNAL (signo, input_available_signal); | |
475 SIGRETURN; | |
476 } | |
477 | |
478 #endif /* SIGIO */ | |
479 | |
480 /* Actual signal handler for SIGALRM. Called when: | |
481 | |
482 -- asynchronous timeouts (added with `add-async-timeout') go off | |
483 | |
484 -- when the poll-for-quit timer (used for C-g handling; more or | |
485 less when SIGIO is unavailable or BROKEN_SIGIO is defined) or | |
486 poll-for-sigchld timer (used when BROKEN_SIGCHLD is defined) go | |
487 off. The latter two timers, if set, normally go off every 1/4 | |
488 of a second -- see NORMAL_QUIT_CHECK_TIMEOUT_MSECS and | |
489 NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS. (Both of these timers are | |
490 treated like other asynchronous timeouts, but special-cased | |
491 in handle_async_timeout_signal().) | |
492 | |
493 -- we called slow_down_interrupts() and SLOWED_DOWN_INTERRUPTS_SECS | |
494 (or a multiple of it) has elapsed. | |
495 | |
496 Note that under Windows, we have no working setitimer(), so we | |
497 simulate it using the multimedia timeout functions, | |
498 e.g. timeSetEvent(). See setitimer() in nt.c. | |
499 | |
500 Note also that we don't actually *do* anything here (except in the | |
501 case of can_break_system_calls). Instead, we just set various | |
502 flags; next time QUIT is called, the flags will cause | |
503 check_what_happened() to be called, at which point we do everything | |
504 indicated by the flags. | |
505 */ | |
506 | |
507 static SIGTYPE | |
508 alarm_signal (int signo) | |
509 { | |
510 something_happened = 1; /* tell QUIT to wake up and call | |
511 check_what_happened() */ | |
512 | |
513 if (interrupts_slowed_down) | |
514 { | |
515 /* we are in "slowed-down interrupts" mode; the only alarm | |
516 happening here is the slowed-down quit-check alarm, so | |
517 we set this flag. | |
518 | |
519 Do NOT set async_timeout_happened, because we don't want | |
520 anyone looking at the timeout queue -- async timeouts | |
521 are disabled. */ | |
522 quit_check_signal_happened = 1; | |
523 quit_check_signal_tick_count++; | |
524 /* make sure we establish the slow timer again. */ | |
525 slowed_interrupt_timeout_happened = 1; | |
526 | |
527 /* can_break_system_calls is set when we want to break out of | |
528 non-interruptible system calls. */ | |
529 if (can_break_system_calls) | |
530 { | |
531 /* reset the flag for safety and such. Do this *before* | |
532 unblocking or reestablishing the signal to avoid potential | |
533 race conditions. */ | |
534 can_break_system_calls = 0; | |
535 #ifndef WIN32_NATIVE | |
536 /* #### I didn't add this WIN32_NATIVE check. I'm not sure | |
537 why it's here. But then again, someone needs to review | |
538 this can_break_system_calls stuff and see if it still | |
539 makes sense. --ben */ | |
540 EMACS_UNBLOCK_SIGNAL (signo); | |
541 EMACS_REESTABLISH_SIGNAL (signo, alarm_signal); | |
542 LONGJMP (break_system_call_jump, 0); | |
543 #endif | |
544 } | |
545 } | |
546 else | |
547 { | |
548 async_timeout_happened = 1; | |
549 if (emacs_is_blocking) | |
550 async_timeout_happened_while_emacs_was_blocking = 1; | |
551 /* #### This is for QUITP. When it is run, it may not be the | |
552 place to do arbitrary stuff like run asynch. handlers, but | |
553 it needs to know whether the poll-for-quit asynch. timeout | |
554 went off. Rather than put the code in to compute this | |
555 specially, we just set this flag. Should fix this. */ | |
556 quit_check_signal_happened = 1; | |
557 | |
558 #ifdef HAVE_UNIXOID_EVENT_LOOP | |
559 signal_fake_event (); | |
560 #endif | |
561 } | |
562 | |
563 EMACS_REESTABLISH_SIGNAL (signo, alarm_signal); | |
564 SIGRETURN; | |
565 } | |
566 | |
428 | 567 /* Set this for debugging, to have a way to get out */ |
568 int stop_character; /* #### not currently implemented */ | |
569 | |
593 | 570 /* Signal handler for SIGINT and SIGQUIT. On TTY's, one of these two |
571 signals will get generated in response to C-g. (When running under | |
572 X, C-g is handled using the SIGIO handler, which sets a flag | |
573 telling the QUIT macro to scan the unread events for a ^G.) | |
574 */ | |
428 | 575 |
576 static SIGTYPE | |
577 interrupt_signal (int sig) | |
578 { | |
579 /* This function can call lisp */ | |
580 /* #### we should NOT be calling lisp from a signal handler, boys | |
581 and girls */ | |
582 /* Must preserve main program's value of errno. */ | |
583 int old_errno = errno; | |
584 | |
585 EMACS_REESTABLISH_SIGNAL (sig, interrupt_signal); | |
586 | |
587 if (sigint_happened && CONSOLEP (Vcontrolling_terminal) && | |
588 CONSOLE_LIVE_P (XCONSOLE (Vcontrolling_terminal)) && | |
589 !emacs_is_blocking) | |
590 { | |
593 | 591 /* #### this is inherited from GNU Emacs. Do we really want this? |
592 --ben */ | |
428 | 593 char c; |
594 fflush (stdout); | |
595 reset_initial_console (); | |
596 EMACS_UNBLOCK_SIGNAL (sig); | |
597 #ifdef SIGTSTP /* Support possible in later USG versions */ | |
598 /* | |
599 * On systems which can suspend the current process and return to the original | |
600 * shell, this command causes the user to end up back at the shell. | |
601 * The "Auto-save" and "Abort" questions are not asked until | |
602 * the user elects to return to emacs, at which point he can save the current | |
603 * job and either dump core or continue. | |
604 */ | |
605 sys_suspend (); | |
606 #else | |
607 /* Perhaps should really fork an inferior shell? | |
608 But that would not provide any way to get back | |
609 to the original shell, ever. */ | |
610 stdout_out ("No support for stopping a process on this operating system;\n"); | |
611 stdout_out ("you can continue or abort.\n"); | |
612 #endif /* not SIGTSTP */ | |
613 stdout_out ("Auto-save? (y or n) "); | |
614 if (((c = getc (stdin)) & ~040) == 'Y') | |
615 Fdo_auto_save (Qnil, Qnil); | |
616 while (c != '\n') | |
617 c = getc (stdin); | |
618 stdout_out ("Abort (and dump core)? (y or n) "); | |
619 if (((c = getc (stdin)) & ~040) == 'Y') | |
2500 | 620 ABORT (); |
428 | 621 while (c != '\n') |
622 c = getc (stdin); | |
623 stdout_out ("Continuing...\n"); | |
624 reinit_initial_console (); | |
625 MARK_FRAME_CHANGED (XFRAME (DEVICE_SELECTED_FRAME | |
626 (XDEVICE (CONSOLE_SELECTED_DEVICE | |
627 (XCONSOLE | |
628 (Vcontrolling_terminal)))))); | |
629 } | |
630 else | |
631 { | |
632 /* Else request quit when it's safe */ | |
633 Vquit_flag = Qt; | |
634 sigint_happened = 1; | |
635 #ifdef HAVE_UNIXOID_EVENT_LOOP | |
636 signal_fake_event (); | |
637 #endif | |
638 } | |
639 errno = old_errno; | |
640 SIGRETURN; | |
641 } | |
642 | |
593 | 643 |
644 /**********************************************************************/ | |
645 /* Control-G checking */ | |
646 /**********************************************************************/ | |
647 | |
2367 | 648 /* |
853 | 649 |
2367 | 650 Info on Control-G checking: |
853 | 651 |
2367 | 652 (Info-goto-node "(internals)Control-G (Quit) Checking") |
653 */ | |
853 | 654 |
771 | 655 /* Defer all checking or processing of C-g. You can do this, for example, |
656 if you want to read C-g's as events. (In that case, you should set | |
657 Vquit_flag to Qnil just before you unbind, because it typically gets set | |
658 as a result of reading C-g.) */ | |
659 | |
660 int | |
428 | 661 begin_dont_check_for_quit (void) |
662 { | |
771 | 663 int depth = specpdl_depth (); |
664 /* As an optimization in QUIT_FLAG_SAYS_SHOULD_QUIT, we bind inhibit-quit | |
665 to t -- it has to be checked anyway, and by doing this, we only need | |
666 to check dont_check_for_quit when quit-flag == `critical', which is | |
667 rare. */ | |
428 | 668 specbind (Qinhibit_quit, Qt); |
853 | 669 internal_bind_int (&dont_check_for_quit, 1); |
771 | 670 |
671 return depth; | |
428 | 672 } |
673 | |
853 | 674 /* If we're inside of a begin_dont_check_for_quit() section, but want |
675 to temporarily enable quit-checking, call this. This is used in | |
676 particular when processing menu filters -- some menu filters do | |
677 antisocial things like load large amounts of Lisp code (custom in | |
678 particular), and we obviously want a way of breaking out of any | |
679 problems. If you do use this, you should really be trapping the | |
680 throw() that comes from the quitting (as does the code that handles | |
681 menus popping up). */ | |
682 | |
428 | 683 int |
853 | 684 begin_do_check_for_quit (void) |
685 { | |
686 int depth = specpdl_depth (); | |
687 specbind (Qinhibit_quit, Qnil); | |
688 internal_bind_int (&dont_check_for_quit, 0); | |
689 /* #### should we set Vquit_flag to Qnil? */ | |
690 return depth; | |
691 } | |
692 | |
693 /* The effect of this function is to set Vquit_flag appropriately if the | |
694 user pressed C-g or Sh-C-g. After this function finishes, Vquit_flag | |
695 will be Qt for C-g, Qcritical for Sh-C-g, and unchanged otherwise. | |
696 The C-g or Sh-C-g is discarded, so it won't be noticed again. | |
697 */ | |
698 | |
2518 | 699 |
700 | |
853 | 701 void |
428 | 702 check_quit (void) |
703 { | |
853 | 704 int specdepth; |
705 | |
428 | 706 if (dont_check_for_quit) |
853 | 707 return; |
428 | 708 |
709 if (quit_check_signal_happened) | |
710 { | |
2034 | 711 #ifdef ERROR_CHECK_TRAPPING_PROBLEMS |
712 /* Since the code below can call Lisp, make sure that proper wrapping is | |
713 in place during redisplay. */ | |
2518 | 714 #if 0 |
2034 | 715 assert_with_message |
716 (proper_redisplay_wrapping_in_place (), | |
717 "QUIT called from within redisplay without being properly wrapped"); | |
2518 | 718 #else |
719 /* FUCKME! It looks like we cannot even check for QUIT, *EVER*, during | |
720 redisplay. Checking for quit can dispatch events, which can enter | |
721 redisplay recursively, which can trip on | |
722 | |
723 Fatal error: assertion failed, file c:\xemacs\build\src\redisplay.c, line 5532, | |
724 !dy->locked | |
725 | |
726 Backtrace given in | |
727 | |
5038 | 728 (Info-goto-node "(internals)Critical Redisplay Sections") |
2518 | 729 |
730 */ | |
731 assert_with_message | |
732 (!in_display, | |
733 "QUIT called from within redisplay without being properly wrapped"); | |
734 #endif /* 0 */ | |
735 #endif /* ERROR_CHECK_TRAPPING_PROBLEMS */ | |
2034 | 736 |
1123 | 737 /* Since arbitrary Lisp code may be executed (e.g. through a menu |
738 filter, see backtrace directly above), GC might happen, | |
771 | 739 which would majorly fuck a lot of things, e.g. re_match() |
740 [string gets relocated] and lots of other code that's not | |
741 prepared to handle GC in QUIT. */ | |
853 | 742 specdepth = begin_gc_forbidden (); |
428 | 743 quit_check_signal_happened = 0; |
744 event_stream_quit_p (); | |
771 | 745 unbind_to (specdepth); |
428 | 746 } |
747 } | |
748 | |
749 | |
750 | |
751 void | |
752 init_poll_for_quit (void) | |
753 { | |
754 #if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT) | |
755 /* Check for C-g every 1/4 of a second. | |
756 | |
757 #### This is just a guess. Some investigation will have to be | |
758 done to see what the best value is. The best value is the | |
759 smallest possible value that doesn't cause a significant amount | |
760 of running time to be spent in C-g checking. */ | |
761 if (!poll_for_quit_id) | |
762 poll_for_quit_id = | |
763 event_stream_generate_wakeup (NORMAL_QUIT_CHECK_TIMEOUT_MSECS, | |
764 NORMAL_QUIT_CHECK_TIMEOUT_MSECS, | |
765 Qnil, Qnil, 1); | |
766 #endif /* not SIGIO and not DONT_POLL_FOR_QUIT */ | |
767 } | |
768 | |
593 | 769 #if 0 /* not used anywhere */ |
770 | |
428 | 771 void |
772 reset_poll_for_quit (void) | |
773 { | |
774 #if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT) | |
775 if (poll_for_quit_id) | |
776 { | |
777 event_stream_disable_wakeup (poll_for_quit_id, 1); | |
778 poll_for_quit_id = 0; | |
779 } | |
780 #endif /* not SIGIO and not DONT_POLL_FOR_QUIT */ | |
781 } | |
782 | |
593 | 783 #endif /* 0 */ |
784 | |
853 | 785 #if defined (HAVE_UNIX_PROCESSES) && !defined (SIGCHLD) |
428 | 786 |
787 static void | |
788 init_poll_for_sigchld (void) | |
789 { | |
790 /* Check for terminated processes every 1/4 of a second. | |
791 | |
792 #### This is just a guess. Some investigation will have to be | |
793 done to see what the best value is. The best value is the | |
794 smallest possible value that doesn't cause a significant amount | |
795 of running time to be spent in process-termination checking. | |
796 */ | |
797 poll_for_sigchld_id = | |
798 event_stream_generate_wakeup (NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS, | |
799 NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS, | |
800 Qnil, Qnil, 1); | |
801 } | |
802 | |
803 #endif /* not SIGCHLD */ | |
804 | |
805 | |
806 /************************************************************************/ | |
807 /* initialization */ | |
808 /************************************************************************/ | |
809 | |
810 /* If we've been nohup'ed, keep it that way. | |
811 This allows `nohup xemacs &' to work. | |
812 More generally, if a normally fatal signal has been redirected | |
813 to SIG_IGN by our invocation environment, trust the environment. | |
814 This keeps xemacs from being killed by a SIGQUIT intended for a | |
815 different process after having been backgrounded under a | |
816 non-job-control shell! */ | |
817 static void | |
818 handle_signal_if_fatal (int signo) | |
819 { | |
613 | 820 if (EMACS_SIGNAL (signo, fatal_error_signal) == SIG_IGN) |
821 EMACS_SIGNAL (signo, SIG_IGN); | |
428 | 822 } |
823 | |
824 void | |
825 init_signals_very_early (void) | |
826 { | |
827 /* Catch all signals that would kill us. | |
828 Don't catch these signals in batch mode if not initialized. | |
829 On some machines, this sets static data that would make | |
830 signal fail to work right when the dumped Emacs is run. */ | |
831 if (noninteractive && !initialized) | |
832 return; | |
833 | |
834 handle_signal_if_fatal (SIGILL); /* ANSI */ | |
835 handle_signal_if_fatal (SIGABRT); /* ANSI */ | |
836 handle_signal_if_fatal (SIGFPE); /* ANSI */ | |
837 handle_signal_if_fatal (SIGSEGV); /* ANSI */ | |
838 handle_signal_if_fatal (SIGTERM); /* ANSI */ | |
839 | |
840 | |
841 #ifdef SIGHUP | |
842 handle_signal_if_fatal (SIGHUP); /* POSIX */ | |
843 #endif | |
844 #ifdef SIGQUIT | |
845 handle_signal_if_fatal (SIGQUIT); /* POSIX */ | |
846 #endif | |
847 #ifdef SIGTRAP | |
848 handle_signal_if_fatal (SIGTRAP); /* POSIX */ | |
849 #endif | |
850 #ifdef SIGUSR1 | |
851 handle_signal_if_fatal (SIGUSR1); /* POSIX */ | |
852 #endif | |
853 #ifdef SIGUSR2 | |
854 handle_signal_if_fatal (SIGUSR2); /* POSIX */ | |
855 #endif | |
856 #ifdef SIGPIPE | |
857 handle_signal_if_fatal (SIGPIPE); /* POSIX */ | |
858 #endif | |
859 #ifdef SIGALRM | |
860 /* This will get reset later, once we're | |
861 capable of handling it properly. */ | |
862 handle_signal_if_fatal (SIGALRM); /* POSIX */ | |
863 #endif | |
864 | |
865 | |
866 #ifdef SIGBUS | |
867 handle_signal_if_fatal (SIGBUS); /* XPG5 */ | |
868 #endif | |
869 #ifdef SIGSYS | |
870 handle_signal_if_fatal (SIGSYS); /* XPG5 */ | |
871 #endif | |
872 #ifdef SIGXCPU | |
873 handle_signal_if_fatal (SIGXCPU); /* XPG5 */ | |
874 #endif | |
875 #ifdef SIGXFSZ | |
876 handle_signal_if_fatal (SIGXFSZ); /* XPG5 */ | |
877 #endif | |
878 #ifdef SIGVTALRM | |
879 handle_signal_if_fatal (SIGVTALRM); /* XPG5 */ | |
880 #endif | |
881 #ifdef SIGPROF | |
882 /* Messes up the REAL profiler */ | |
883 /* handle_signal_if_fatal (SIGPROF); */ /* XPG5 */ | |
884 #endif | |
885 | |
886 | |
887 #ifdef SIGHWE | |
888 handle_signal_if_fatal (SIGHWE); | |
889 #endif | |
890 #ifdef SIGPRE | |
891 handle_signal_if_fatal (SIGPRE); | |
892 #endif | |
893 #ifdef SIGORE | |
894 handle_signal_if_fatal (SIGORE); | |
895 #endif | |
896 #ifdef SIGUME | |
897 handle_signal_if_fatal (SIGUME); | |
898 #endif | |
899 #ifdef SIGDLK | |
900 handle_signal_if_fatal (SIGDLK); | |
901 #endif | |
902 #ifdef SIGCPULIM | |
903 handle_signal_if_fatal (SIGCPULIM); | |
904 #endif | |
905 #ifdef SIGIOT | |
906 handle_signal_if_fatal (SIGIOT); | |
907 #endif | |
908 #ifdef SIGEMT | |
909 handle_signal_if_fatal (SIGEMT); | |
910 #endif | |
911 #ifdef SIGLOST | |
912 handle_signal_if_fatal (SIGLOST); | |
913 #endif | |
914 #ifdef SIGSTKFLT /* coprocessor stack fault under Linux */ | |
915 handle_signal_if_fatal (SIGSTKFLT); | |
916 #endif | |
917 #ifdef SIGUNUSED /* exists under Linux, and will kill process! */ | |
918 handle_signal_if_fatal (SIGUNUSED); | |
919 #endif | |
920 | |
921 #ifdef AIX | |
922 /* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */ | |
923 #ifndef _I386 | |
924 handle_signal_if_fatal (SIGIOINT); | |
925 #endif | |
926 handle_signal_if_fatal (SIGGRANT); | |
927 handle_signal_if_fatal (SIGRETRACT); | |
928 handle_signal_if_fatal (SIGSOUND); | |
929 handle_signal_if_fatal (SIGMSG); | |
930 #endif /* AIX */ | |
931 | |
932 #ifdef SIGDANGER | |
933 /* This just means available memory is getting low. */ | |
613 | 934 EMACS_SIGNAL (SIGDANGER, memory_warning_signal); |
428 | 935 #endif |
936 } | |
937 | |
938 void | |
939 syms_of_signal (void) | |
940 { | |
941 DEFSUBR (Fwaiting_for_user_input_p); | |
942 } | |
943 | |
944 void | |
945 init_interrupts_late (void) | |
946 { | |
947 if (!noninteractive) | |
948 { | |
613 | 949 EMACS_SIGNAL (SIGINT, interrupt_signal); |
428 | 950 #ifdef HAVE_TERMIO |
951 /* On systems with TERMIO, C-g is set up for both SIGINT and SIGQUIT | |
952 and we can't tell which one it will give us. */ | |
613 | 953 EMACS_SIGNAL (SIGQUIT, interrupt_signal); |
428 | 954 #endif /* HAVE_TERMIO */ |
955 init_async_timeouts (); | |
956 #ifdef SIGIO | |
613 | 957 EMACS_SIGNAL (SIGIO, input_available_signal); |
428 | 958 # ifdef SIGPOLL /* XPG5 */ |
959 /* Some systems (e.g. Motorola SVR4) losingly have different | |
960 values for SIGIO and SIGPOLL, and send SIGPOLL instead of | |
961 SIGIO. On those same systems, an uncaught SIGPOLL kills the | |
962 process. */ | |
613 | 963 EMACS_SIGNAL (SIGPOLL, input_available_signal); |
428 | 964 # endif |
965 #elif !defined (DONT_POLL_FOR_QUIT) | |
966 init_poll_for_quit (); | |
967 #endif | |
968 } | |
969 | |
853 | 970 #if defined (HAVE_UNIX_PROCESSES) && !defined (SIGCHLD) |
428 | 971 init_poll_for_sigchld (); |
972 #endif | |
973 | |
974 EMACS_UNBLOCK_ALL_SIGNALS (); | |
975 | |
976 interrupts_initted = 1; | |
977 } | |
978 |