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