Mercurial > hg > xemacs-beta
annotate src/signal.c @ 5925:08cfc8f77fb6 cygwin
make space for long ptr, and store as such, for frame in WINDOW data,
add a bit more debugging to debug-mswindow,
Vin Shelton patch to fix M-x shell
| author | Henry Thompson <ht@markup.co.uk> |
|---|---|
| date | Fri, 27 Feb 2015 17:41:20 +0000 |
| 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 |
