Mercurial > hg > xemacs-beta
comparison src/signal.c @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | 0293115a14e9 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 /* Handling asynchronous signals. | |
2 Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. | |
3 Copyright (C) 1995, 1996 Ben Wing. | |
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 /* Just to make sure we don't use any global vars below */ | |
25 #define DONT_DECLARE_MAC_VARS | |
26 | |
27 #include <config.h> | |
28 #include "lisp.h" | |
29 | |
30 #include "console.h" | |
31 #include "events.h" /* for signal_fake_event() */ | |
32 #include "frame.h" | |
33 #include "sysdep.h" | |
34 #include "syssignal.h" | |
35 #include "systime.h" | |
36 | |
37 #include <errno.h> | |
38 | |
39 /* Set to 1 when a quit-check signal (either a SIGIO interrupt or | |
40 the asynch. timeout for poll-for-quit) occurs. The QUITP | |
41 macro may look at this. */ | |
42 volatile int quit_check_signal_happened; | |
43 | |
44 /* Count of the number of times a quit-check signal has occurred. | |
45 Some stuff in event-Xt.c looks at this. */ | |
46 volatile int quit_check_signal_tick_count; | |
47 | |
48 /* Set to 1 when a SIGINT (or SIGQUIT) interrupt is processed. | |
49 maybe_read_quit_event() looks at this. */ | |
50 volatile int sigint_happened; | |
51 | |
52 /* Set to 1 when an asynch. timeout signal occurs. */ | |
53 static volatile int alarm_happened; | |
54 | |
55 /* This is used to synchronize setting the waiting_for_user_input_p | |
56 flag. */ | |
57 static volatile int alarm_happened_while_emacs_was_blocking; | |
58 | |
59 /* See check_quit() for when this is set. */ | |
60 int dont_check_for_quit; | |
61 | |
62 #if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT) | |
63 int poll_for_quit_id; | |
64 #endif | |
65 | |
66 #ifndef SIGCHLD | |
67 int poll_for_sigchld_id; | |
68 #endif | |
69 | |
70 /* This variable is used to communicate to a lisp | |
71 process-filter/sentinel/asynchronous callback (via the function | |
72 Fwaiting_for_user_input_p below) whether XEmacs was waiting for | |
73 user-input when that process-filter was called. */ | |
74 static int waiting_for_user_input_p; | |
75 | |
76 static int interrupts_slowed_down; | |
77 | |
78 #define SLOWED_DOWN_INTERRUPTS_SECS 5 | |
79 #define NORMAL_QUIT_CHECK_TIMEOUT_MSECS 250 | |
80 #define NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS 250 | |
81 | |
82 /* Used so that signals can break out of system calls that aren't | |
83 naturally interruptible. */ | |
84 | |
85 JMP_BUF break_system_call_jump; | |
86 int can_break_system_calls; | |
87 | |
88 | |
89 /**********************************************************************/ | |
90 /* Asynchronous timeout functions */ | |
91 /**********************************************************************/ | |
92 | |
93 /* The pending timers are stored in an ordered list, where the first timer | |
94 on the list is the first one to fire. Times recorded here are | |
95 absolute. */ | |
96 static struct low_level_timeout *async_timer_queue; | |
97 | |
98 /* Nonzero means async timers are temporarily suppressed. */ | |
99 static int async_timer_suppress_count; | |
100 | |
101 static void | |
102 set_one_shot_timer (EMACS_TIME interval) | |
103 { | |
104 #ifdef HAVE_SETITIMER | |
105 struct itimerval it; | |
106 it.it_value = interval; | |
107 EMACS_SET_SECS_USECS (it.it_interval, 0, 0); | |
108 setitimer (ITIMER_REAL, &it, 0); | |
109 #else | |
110 int secs; | |
111 EMACS_TIME_TO_INT (interval, secs); | |
112 alarm (secs); | |
113 #endif | |
114 } | |
115 | |
116 static void | |
117 reset_interval_timer (void) | |
118 { | |
119 EMACS_TIME interval; | |
120 | |
121 /* Get the interval to set. If an interval is available, | |
122 make sure it's not zero (this is a valid return, but it will | |
123 cause the timer to get disabled, so convert it to a very short | |
124 time). */ | |
125 if (get_low_level_timeout_interval (async_timer_queue, &interval)) | |
126 { | |
127 if (EMACS_SECS (interval) == 0 && EMACS_USECS (interval) == 0) | |
128 EMACS_SET_USECS (interval, 1); | |
129 } | |
130 else | |
131 /* A time of 0 means "disable". */ | |
132 EMACS_SET_SECS_USECS (interval, 0, 0); | |
133 | |
134 set_one_shot_timer (interval); | |
135 } | |
136 | |
137 int | |
138 event_stream_add_async_timeout (EMACS_TIME thyme) | |
139 { | |
140 int id = add_low_level_timeout (&async_timer_queue, thyme); | |
141 | |
142 /* If this timeout is at the head of the queue, then we need to | |
143 set the timer right now for this timeout. Otherwise, things | |
144 are fine as-is; after the timers ahead of us are signalled, | |
145 the timer will be set for us. */ | |
146 | |
147 if (async_timer_queue->id == id) | |
148 reset_interval_timer (); | |
149 | |
150 return id; | |
151 } | |
152 | |
153 void | |
154 event_stream_remove_async_timeout (int id) | |
155 { | |
156 int first = (async_timer_queue && async_timer_queue->id == id); | |
157 remove_low_level_timeout (&async_timer_queue, id); | |
158 | |
159 /* If we removed the timeout from the head of the queue, then | |
160 we need to reset the interval timer right now. */ | |
161 if (first) | |
162 reset_interval_timer (); | |
163 } | |
164 | |
165 /* Handle an alarm once each second and read pending input | |
166 so as to handle a C-g if it comes in. */ | |
167 | |
168 static SIGTYPE | |
169 alarm_signal (int signo) | |
170 { | |
171 if (interrupts_slowed_down) | |
172 { | |
173 something_happened = 1; /* tell QUIT to wake up */ | |
174 /* we are in "slowed-down interrupts" mode; the only alarm | |
175 happening here is the slowed-down quit-check alarm, so | |
176 we set this flag. | |
177 | |
178 Do NOT set alarm_happened, because we don't want anyone | |
179 looking at the timeout queue. We didn't set it and | |
180 it needs to stay the way it is. */ | |
181 quit_check_signal_happened = 1; | |
182 | |
183 /* can_break_system_calls is set when we want to break out of | |
184 non-interruptible system calls. */ | |
185 if (can_break_system_calls) | |
186 { | |
187 /* reset the flag for safety and such. Do this *before* | |
188 unblocking or reestablishing the signal to avoid potential | |
189 race conditions. */ | |
190 can_break_system_calls = 0; | |
191 EMACS_UNBLOCK_SIGNAL (signo); | |
192 EMACS_REESTABLISH_SIGNAL (signo, alarm_signal); | |
193 LONGJMP (break_system_call_jump, 0); | |
194 } | |
195 | |
196 EMACS_REESTABLISH_SIGNAL (signo, alarm_signal); | |
197 SIGRETURN; | |
198 } | |
199 | |
200 something_happened = 1; /* tell QUIT to wake up */ | |
201 alarm_happened = 1; | |
202 if (emacs_is_blocking) | |
203 alarm_happened_while_emacs_was_blocking = 1; | |
204 /* #### This is for QUITP. When it is run, it may not be the | |
205 place to do arbitrary stuff like run asynch. handlers, but | |
206 it needs to know whether the poll-for-quit asynch. timeout | |
207 went off. Rather than put the code in to compute this | |
208 specially, we just set this flag. Should fix this. */ | |
209 quit_check_signal_happened = 1; | |
210 signal_fake_event (); | |
211 | |
212 EMACS_REESTABLISH_SIGNAL (signo, alarm_signal); | |
213 SIGRETURN; | |
214 } | |
215 | |
216 static void | |
217 init_async_timeouts (void) | |
218 { | |
219 signal (SIGALRM, alarm_signal); | |
220 async_timer_suppress_count = 0; | |
221 } | |
222 | |
223 /* Turn off async timeouts. */ | |
224 | |
225 static void | |
226 stop_async_timeouts (void) | |
227 { | |
228 if (async_timer_suppress_count == 0) | |
229 { | |
230 /* If timer was on, turn it off. */ | |
231 EMACS_TIME thyme; | |
232 EMACS_SET_SECS_USECS (thyme, 0, 0); | |
233 set_one_shot_timer (thyme); | |
234 } | |
235 async_timer_suppress_count++; | |
236 } | |
237 | |
238 /* Turn on async timeouts again. */ | |
239 | |
240 static void | |
241 start_async_timeouts (void) | |
242 { | |
243 assert (async_timer_suppress_count > 0); | |
244 async_timer_suppress_count--; | |
245 if (async_timer_suppress_count == 0) | |
246 { | |
247 /* Some callers turn off async timeouts and then use the alarm | |
248 for their own purposes; so reinitialize everything. */ | |
249 signal (SIGALRM, alarm_signal); | |
250 reset_interval_timer (); | |
251 } | |
252 } | |
253 | |
254 /* Some functions don't like being interrupted with SIGALRM or SIGIO. | |
255 Previously we were calling stop_interrupts() / start_interrupts(), | |
256 but then if the program hangs in one of those functions, e.g. | |
257 waiting for a connect(), we're really screwed. So instead we | |
258 just "slow them down". We do this by disabling all interrupts | |
259 and then installing a timer of length fairly large, like 5 or | |
260 10 secs. That way, any "legitimate" connections (which should | |
261 take a fairly short amount of time) go through OK, but we can | |
262 interrupt bogus ones. */ | |
263 | |
264 void | |
265 slow_down_interrupts (void) | |
266 { | |
267 EMACS_TIME thyme; | |
268 | |
269 /* We have to set the flag *before* setting the slowed-down timer, | |
270 to avoid a race condition -- if the signal occurs between the | |
271 call to set_one_shot_timer() and the setting of this flag, | |
272 alarm_happened will get set, which will be a Bad Thing if | |
273 there were no timeouts on the queue. */ | |
274 interrupts_slowed_down++; | |
275 if (interrupts_slowed_down == 1) | |
276 { | |
277 stop_interrupts (); | |
278 EMACS_SET_SECS_USECS (thyme, SLOWED_DOWN_INTERRUPTS_SECS, 0); | |
279 set_one_shot_timer (thyme); | |
280 } | |
281 } | |
282 | |
283 void | |
284 speed_up_interrupts (void) | |
285 { | |
286 if (interrupts_slowed_down > 0) | |
287 { | |
288 start_interrupts (); | |
289 /* Change this flag AFTER fiddling with interrupts, for the same | |
290 race-condition reasons as above. */ | |
291 interrupts_slowed_down--; | |
292 } | |
293 } | |
294 | |
295 static void | |
296 handle_alarm_going_off (void) | |
297 { | |
298 int interval_id; | |
299 | |
300 /* If asynch. timeouts are blocked, then don't do anything now, | |
301 but make this function get called again next QUIT. | |
302 | |
303 #### This is a bit inefficient because there will be function call | |
304 overhead each time QUIT occurs. */ | |
305 | |
306 if (!NILP (Vinhibit_quit)) | |
307 { | |
308 something_happened = 1; | |
309 alarm_happened = 1; | |
310 return; | |
311 } | |
312 | |
313 interval_id = pop_low_level_timeout (&async_timer_queue, 0); | |
314 | |
315 reset_interval_timer (); | |
316 if (alarm_happened_while_emacs_was_blocking) | |
317 { | |
318 alarm_happened_while_emacs_was_blocking = 0; | |
319 waiting_for_user_input_p = 1; | |
320 } | |
321 event_stream_deal_with_async_timeout (interval_id); | |
322 waiting_for_user_input_p = 0; | |
323 } | |
324 | |
325 #ifdef HAVE_SETITIMER | |
326 unsigned int | |
327 alarm (unsigned int howlong) | |
328 { | |
329 struct itimerval old_it, new_it; | |
330 | |
331 /* If alarm() gets called when polling isn't disabled, it can mess | |
332 up the periodic timer. */ | |
333 assert (async_timer_suppress_count > 0); | |
334 | |
335 new_it.it_value.tv_sec = howlong; | |
336 new_it.it_value.tv_usec = 0; | |
337 new_it.it_interval.tv_sec = 0; | |
338 new_it.it_interval.tv_usec = 0; | |
339 setitimer (ITIMER_REAL, &new_it, &old_it); | |
340 | |
341 /* Never return zero if there was a timer outstanding. */ | |
342 return old_it.it_value.tv_sec + (old_it.it_value.tv_usec > 0 ? 1 : 0); | |
343 } | |
344 #endif | |
345 | |
346 DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, | |
347 Swaiting_for_user_input_p, | |
348 0, 0, 0 /* | |
349 Return non-nil if XEmacs is waiting for input from the user. | |
350 This is intended for use by asynchronous timeout callbacks and by | |
351 asynchronous process output filters and sentinels (not yet implemented | |
352 in XEmacs). It will always be nil if XEmacs is not inside of | |
353 an asynchronout timeout or process callback. | |
354 */ ) | |
355 () | |
356 { | |
357 return ((waiting_for_user_input_p) ? Qt : Qnil); | |
358 } | |
359 | |
360 | |
361 /**********************************************************************/ | |
362 /* Control-G checking */ | |
363 /**********************************************************************/ | |
364 | |
365 /* Set this for debugging, to have a way to get out */ | |
366 int stop_character; /* #### not currently implemented */ | |
367 | |
368 /* This routine is called in response to a SIGINT or SIGQUIT. | |
369 On TTY's, one of these two signals will get generated in response | |
370 to C-g. (When running under X, C-g is handled using the SIGIO | |
371 handler, which sets a flag telling the QUIT macro to scan the | |
372 unread events for a ^G.) | |
373 | |
374 Otherwise it sets the Lisp variable quit-flag not-nil. | |
375 This causes eval to throw, when it gets a chance. | |
376 If quit-flag is already non-nil, it stops the job right away. */ | |
377 | |
378 static SIGTYPE | |
379 interrupt_signal (int sig) | |
380 { | |
381 /* This function can GC (?!) */ | |
382 /* Must preserve main program's value of errno. */ | |
383 int old_errno = errno; | |
384 | |
385 EMACS_REESTABLISH_SIGNAL (sig, interrupt_signal); | |
386 | |
387 /* with the macroized error-checking stuff, the garbage below | |
388 may mess things up because XCONSOLE() and such can use and | |
389 change global vars. */ | |
390 #if ! (defined (ERROR_CHECK_TYPECHECK) && defined (MACROIZE_ERROR_CHECKING)) | |
391 if (sigint_happened && CONSOLEP (Vcontrolling_terminal) && | |
392 CONSOLE_LIVE_P (XCONSOLE (Vcontrolling_terminal)) && | |
393 !emacs_is_blocking) | |
394 { | |
395 char c; | |
396 fflush (stdout); | |
397 reset_initial_console (); | |
398 EMACS_UNBLOCK_SIGNAL (sig); | |
399 #ifdef SIGTSTP /* Support possible in later USG versions */ | |
400 /* | |
401 * On systems which can suspend the current process and return to the original | |
402 * shell, this command causes the user to end up back at the shell. | |
403 * The "Auto-save" and "Abort" questions are not asked until | |
404 * the user elects to return to emacs, at which point he can save the current | |
405 * job and either dump core or continue. | |
406 */ | |
407 sys_suspend (); | |
408 #else | |
409 #ifdef VMS | |
410 if (sys_suspend () == -1) | |
411 { | |
412 stdout_out ("Not running as a subprocess;\n"); | |
413 stdout_out ("you can continue or abort.\n"); | |
414 } | |
415 #else /* not VMS */ | |
416 /* Perhaps should really fork an inferior shell? | |
417 But that would not provide any way to get back | |
418 to the original shell, ever. */ | |
419 stdout_out ("No support for stopping a process on this operating system;\n"); | |
420 stdout_out ("you can continue or abort.\n"); | |
421 #endif /* not VMS */ | |
422 #endif /* not SIGTSTP */ | |
423 stdout_out ("Auto-save? (y or n) "); | |
424 fflush (stdout); | |
425 if (((c = getc (stdin)) & ~040) == 'Y') | |
426 Fdo_auto_save (Qnil, Qnil); | |
427 while (c != '\n') | |
428 c = getc (stdin); | |
429 #ifdef VMS | |
430 stdout_out ("Abort (and enter debugger)? (y or n) "); | |
431 #else /* not VMS */ | |
432 stdout_out ("Abort (and dump core)? (y or n) "); | |
433 #endif /* not VMS */ | |
434 fflush (stdout); | |
435 if (((c = getc (stdin)) & ~040) == 'Y') | |
436 abort (); | |
437 while (c != '\n') | |
438 c = getc (stdin); | |
439 stdout_out ("Continuing...\n"); | |
440 fflush (stdout); | |
441 reinit_initial_console (); | |
442 MARK_FRAME_CHANGED (XFRAME (DEVICE_SELECTED_FRAME | |
443 (XDEVICE (CONSOLE_SELECTED_DEVICE | |
444 (XCONSOLE | |
445 (Vcontrolling_terminal)))))); | |
446 } | |
447 else | |
448 #endif /* ! (defined (ERROR_CHECKING) && defined (MACROIZE_ERROR_CHECKING)) */ | |
449 { | |
450 /* Else request quit when it's safe */ | |
451 Vquit_flag = Qt; | |
452 sigint_happened = 1; | |
453 signal_fake_event (); | |
454 } | |
455 errno = old_errno; | |
456 SIGRETURN; | |
457 } | |
458 | |
459 static Lisp_Object | |
460 restore_dont_check_for_quit (Lisp_Object val) | |
461 { | |
462 dont_check_for_quit = XINT (val); | |
463 return Qnil; | |
464 } | |
465 | |
466 void | |
467 begin_dont_check_for_quit (void) | |
468 { | |
469 specbind (Qinhibit_quit, Qt); | |
470 record_unwind_protect (restore_dont_check_for_quit, | |
471 make_int (dont_check_for_quit)); | |
472 dont_check_for_quit = 1; | |
473 } | |
474 | |
475 /* The effect of this function is to set Vquit_flag if the user pressed | |
476 ^G and discard the ^G, so as to not notice the same ^G again. */ | |
477 int | |
478 check_quit (void) | |
479 { | |
480 /* dont_check_for_quit is set in two circumstances: | |
481 | |
482 (1) when we are in the process of changing the window | |
483 configuration. The frame might be in an inconsistent state, | |
484 which will cause assertion failures if we check for QUIT. | |
485 | |
486 (2) when we are reading events, and want to read the C-g | |
487 as an event. The normal check for quit will discard the C-g, | |
488 which would be bad. | |
489 | |
490 #### C-g is still often read as quit, e.g. if you type C-x C-g | |
491 (the C-g happens during the sit-for in maybe_echo_keys(); even | |
492 if we attempt to inhibit quit here, there is still a check | |
493 later on for QUIT. To fix this properly requires a fairly | |
494 substantial overhaul of the quit-checking code, which is | |
495 probably not worth it.) | |
496 | |
497 We should *not* conditionalize on Vinhibit_quit, or | |
498 critical-quit (Control-Shift-G) won't work right. */ | |
499 | |
500 if (dont_check_for_quit) | |
501 return 0; | |
502 | |
503 if (quit_check_signal_happened) | |
504 { | |
505 quit_check_signal_happened = 0; | |
506 event_stream_quit_p (); | |
507 return 1; | |
508 } | |
509 else | |
510 return 0; | |
511 } | |
512 | |
513 int | |
514 check_what_happened (void) /* called from QUIT when | |
515 something_happened gets set */ | |
516 { | |
517 something_happened = 0; | |
518 if (alarm_happened) | |
519 { | |
520 alarm_happened = 0; | |
521 handle_alarm_going_off (); | |
522 } | |
523 return check_quit (); | |
524 } | |
525 | |
526 | |
527 | |
528 void | |
529 init_poll_for_quit (void) | |
530 { | |
531 #if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT) | |
532 /* Check for C-g every 1/4 of a second. | |
533 | |
534 #### This is just a guess. Some investigation will have to be | |
535 done to see what the best value is. The best value is the | |
536 smallest possible value that doesn't cause a significant amount | |
537 of running time to be spent in C-g checking. */ | |
538 if (!poll_for_quit_id) | |
539 poll_for_quit_id = | |
540 event_stream_generate_wakeup (NORMAL_QUIT_CHECK_TIMEOUT_MSECS, | |
541 NORMAL_QUIT_CHECK_TIMEOUT_MSECS, | |
542 Qnil, Qnil, 1); | |
543 #endif /* not SIGIO and not DONT_POLL_FOR_QUIT */ | |
544 } | |
545 | |
546 void | |
547 reset_poll_for_quit (void) | |
548 { | |
549 #if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT) | |
550 if (poll_for_quit_id) | |
551 { | |
552 event_stream_disable_wakeup (poll_for_quit_id, 1); | |
553 poll_for_quit_id = 0; | |
554 } | |
555 #endif /* not SIGIO and not DONT_POLL_FOR_QUIT */ | |
556 } | |
557 | |
558 #ifndef SIGCHLD | |
559 | |
560 static void | |
561 init_poll_for_sigchld (void) | |
562 { | |
563 /* Check for terminated processes every 1/4 of a second. | |
564 | |
565 #### This is just a guess. Some investigation will have to be | |
566 done to see what the best value is. The best value is the | |
567 smallest possible value that doesn't cause a significant amount | |
568 of running time to be spent in process-termination checking. | |
569 */ | |
570 poll_for_sigchld_id = | |
571 event_stream_generate_wakeup (NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS, | |
572 NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS, | |
573 Qnil, Qnil, 1); | |
574 } | |
575 | |
576 #endif /* not SIGCHLD */ | |
577 | |
578 #ifdef SIGIO | |
579 | |
580 static void | |
581 input_available_signal (int signo) | |
582 { | |
583 something_happened = 1; /* tell QUIT to wake up */ | |
584 quit_check_signal_happened = 1; | |
585 quit_check_signal_tick_count++; | |
586 EMACS_REESTABLISH_SIGNAL (signo, input_available_signal); | |
587 SIGRETURN; | |
588 } | |
589 | |
590 #endif /* SIGIO */ | |
591 | |
592 | |
593 /**********************************************************************/ | |
594 /* Enabling/disabling signals */ | |
595 /**********************************************************************/ | |
596 | |
597 static int interrupts_initted; | |
598 | |
599 void | |
600 stop_interrupts (void) | |
601 { | |
602 if (!interrupts_initted) | |
603 return; | |
604 #ifdef SIGIO | |
605 unrequest_sigio (); | |
606 #endif | |
607 stop_async_timeouts (); | |
608 } | |
609 | |
610 void | |
611 start_interrupts (void) | |
612 { | |
613 if (!interrupts_initted) | |
614 return; | |
615 #ifdef SIGIO | |
616 request_sigio (); | |
617 #endif | |
618 start_async_timeouts (); | |
619 } | |
620 | |
621 /* Cheesy but workable implementation of sleep() that doesn't | |
622 interfere with out periodic timers. */ | |
623 | |
624 void | |
625 emacs_sleep (int secs) | |
626 { | |
627 stop_interrupts (); | |
628 sleep (secs); | |
629 start_interrupts (); | |
630 } | |
631 | |
632 | |
633 /************************************************************************/ | |
634 /* initialization */ | |
635 /************************************************************************/ | |
636 | |
637 void | |
638 init_signals_very_early (void) | |
639 { | |
640 /* Catch all signals that would kill us. */ | |
641 if (! noninteractive || initialized) | |
642 { | |
643 /* Don't catch these signals in batch mode if not initialized. | |
644 On some machines, this sets static data that would make | |
645 signal fail to work right when the dumped Emacs is run. */ | |
646 signal (SIGHUP, fatal_error_signal); | |
647 signal (SIGQUIT, fatal_error_signal); | |
648 signal (SIGILL, fatal_error_signal); | |
649 signal (SIGTRAP, fatal_error_signal); | |
650 #ifdef SIGABRT | |
651 signal (SIGABRT, fatal_error_signal); | |
652 #endif | |
653 #ifdef SIGHWE | |
654 signal (SIGHWE, fatal_error_signal); | |
655 #endif | |
656 #ifdef SIGPRE | |
657 signal (SIGPRE, fatal_error_signal); | |
658 #endif | |
659 #ifdef SIGORE | |
660 signal (SIGORE, fatal_error_signal); | |
661 #endif | |
662 #ifdef SIGUME | |
663 signal (SIGUME, fatal_error_signal); | |
664 #endif | |
665 #ifdef SIGDLK | |
666 signal (SIGDLK, fatal_error_signal); | |
667 #endif | |
668 #ifdef SIGCPULIM | |
669 signal (SIGCPULIM, fatal_error_signal); | |
670 #endif | |
671 #ifdef SIGIOT | |
672 signal (SIGIOT, fatal_error_signal); | |
673 #endif | |
674 #ifdef SIGEMT | |
675 signal (SIGEMT, fatal_error_signal); | |
676 #endif | |
677 signal (SIGFPE, fatal_error_signal); | |
678 #ifdef SIGBUS | |
679 signal (SIGBUS, fatal_error_signal); | |
680 #endif | |
681 signal (SIGSEGV, fatal_error_signal); | |
682 #ifdef SIGSYS | |
683 signal (SIGSYS, fatal_error_signal); | |
684 #endif | |
685 signal (SIGPIPE, fatal_error_signal); | |
686 signal (SIGTERM, fatal_error_signal); | |
687 #ifdef SIGXCPU | |
688 signal (SIGXCPU, fatal_error_signal); | |
689 #endif | |
690 #ifdef SIGXFSZ | |
691 signal (SIGXFSZ, fatal_error_signal); | |
692 #endif /* SIGXFSZ */ | |
693 | |
694 #ifdef SIGDANGER | |
695 /* This just means available memory is getting low. */ | |
696 signal (SIGDANGER, memory_warning_signal); | |
697 #endif | |
698 | |
699 #ifdef SIGLOST | |
700 signal (SIGLOST, fatal_error_signal); | |
701 #endif | |
702 #ifdef SIGSTKFLT /* coprocessor stack fault under Linux */ | |
703 signal (SIGSTKFLT, fatal_error_signal); | |
704 #endif | |
705 #ifdef SIGUSR1 | |
706 signal (SIGUSR1, fatal_error_signal); | |
707 #endif | |
708 #ifdef SIGUSR2 | |
709 signal (SIGUSR2, fatal_error_signal); | |
710 #endif | |
711 #ifdef SIGALRM | |
712 /* This will get reset later, once we're capable of handling | |
713 this properly. */ | |
714 signal (SIGALRM, fatal_error_signal); | |
715 #endif | |
716 #ifdef SIGVTALRM | |
717 signal (SIGVTALRM, fatal_error_signal); | |
718 #endif | |
719 #ifdef SIGPROF | |
720 signal (SIGPROF, fatal_error_signal); | |
721 #endif | |
722 #ifdef SIGUNUSED /* exists under Linux, and will kill process! */ | |
723 signal (SIGUNUSED, fatal_error_signal); | |
724 #endif | |
725 | |
726 #ifdef AIX | |
727 /* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */ | |
728 #ifndef _I386 | |
729 signal (SIGIOINT, fatal_error_signal); | |
730 #endif | |
731 signal (SIGGRANT, fatal_error_signal); | |
732 signal (SIGRETRACT, fatal_error_signal); | |
733 signal (SIGSOUND, fatal_error_signal); | |
734 signal (SIGMSG, fatal_error_signal); | |
735 #endif /* AIX */ | |
736 } | |
737 } | |
738 | |
739 void | |
740 syms_of_signal (void) | |
741 { | |
742 defsubr (&Swaiting_for_user_input_p); | |
743 } | |
744 | |
745 void | |
746 init_interrupts_late (void) | |
747 { | |
748 if (!noninteractive) | |
749 { | |
750 signal (SIGINT, interrupt_signal); | |
751 #ifdef HAVE_TERMIO | |
752 /* On systems with TERMIO, C-g is set up for both SIGINT and SIGQUIT | |
753 and we can't tell which one it will give us. */ | |
754 signal (SIGQUIT, interrupt_signal); | |
755 #endif /* HAVE_TERMIO */ | |
756 init_async_timeouts (); | |
757 #ifdef SIGIO | |
758 signal (SIGIO, input_available_signal); | |
759 # ifdef SIGPOLL | |
760 /* Some systems (e.g. Motorola SVR4) losingly have different | |
761 values for SIGIO and SIGPOLL, and send SIGPOLL instead of | |
762 SIGIO. On those same systems, an uncaught SIGPOLL kills the | |
763 process. */ | |
764 signal (SIGPOLL, input_available_signal); | |
765 # endif | |
766 #elif !defined (DONT_POLL_FOR_QUIT) | |
767 init_poll_for_quit (); | |
768 #endif | |
769 } | |
770 | |
771 #ifndef SIGCHLD | |
772 init_poll_for_sigchld (); | |
773 #endif | |
774 | |
775 EMACS_UNBLOCK_ALL_SIGNALS (); | |
776 | |
777 interrupts_initted = 1; | |
778 } | |
779 |