comparison src/signal.c @ 853:2b6fa2618f76

[xemacs-hg @ 2002-05-28 08:44:22 by ben] merge my stderr-proc ws make-docfile.c: Fix places where we forget to check for EOF. code-init.el: Don't use CRLF conversion by default on process output. CMD.EXE and friends work both ways but Cygwin programs don't like the CRs. code-process.el, multicast.el, process.el: Removed. Improvements to call-process-internal: -- allows a buffer to be specified for input and stderr output -- use it on all systems -- implement C-g as documented -- clean up and comment call-process-region uses new call-process facilities; no temp file. remove duplicate funs in process.el. comment exactly how coding systems work and fix various problems. open-multicast-group now does similar coding-system frobbing to open-network-stream. dumped-lisp.el, faces.el, msw-faces.el: Fix some hidden errors due to code not being defined at the right time. xemacs.mak: Add -DSTRICT. ================================================================ ALLOW SEPARATION OF STDOUT AND STDERR IN PROCESSES ================================================================ Standard output and standard error can be processed separately in a process. Each can have its own buffer, its own mark in that buffer, and its filter function. You can specify a separate buffer for stderr in `start-process' to get things started, or use the new primitives: set-process-stderr-buffer process-stderr-buffer process-stderr-mark set-process-stderr-filter process-stderr-filter Also, process-send-region takes a 4th optional arg, a buffer. Currently always uses a pipe() under Unix to read the error output. (#### Would a PTY be better?) sysdep.h, sysproc.h, unexfreebsd.c, unexsunos4.c, nt.c, emacs.c, callproc.c, symsinit.h, sysdep.c, Makefile.in.in, process-unix.c: Delete callproc.c. Move child_setup() to process-unix.c. wait_for_termination() now only needed on a few really old systems. console-msw.h, event-Xt.c, event-msw.c, event-stream.c, event-tty.c, event-unixoid.c, events.h, process-nt.c, process-unix.c, process.c, process.h, procimpl.h: Rewrite the process methods to handle a separate channel for error input. Create Lstreams for reading in the error channel. Many process methods need change. In general the changes are fairly clear as they involve duplicating what's used for reading the normal stdout and changing for stderr -- although tedious, as such changes are required throughout the entire process code. Rewrote the code that reads process output to do two loops, one for stdout and one for stderr. gpmevent.c, tooltalk.c: set_process_filter takes an argument for stderr. ================================================================ NEW ERROR-TRAPPING MECHANISM ================================================================ Totally rewrite error trapping code to be unified and support more features. Basic function is call_trapping_problems(), which lets you specify, by means of flags, what sorts of problems you want trapped. these can include -- quit -- errors -- throws past the function -- creation of "display objects" (e.g. buffers) -- deletion of already-existing "display objects" (e.g. buffers) -- modification of already-existing buffers -- entering the debugger -- gc -- errors->warnings (ala suspended errors) etc. All other error funs rewritten in terms of this one. Various older mechanisms removed or rewritten. window.c, insdel.c, console.c, buffer.c, device.c, frame.c: When creating a display object, added call to note_object_created(), for use with trapping_problems mechanism. When deleting, call check_allowed_operation() and note_object deleted(). The trapping-problems code records the objects created since the call-trapping-problems began. Those objects can be deleted, but none others (i.e. previously existing ones). bytecode.c, cmdloop.c: internal_catch takes another arg. eval.c: Add long comments describing the "five lists" used to maintain state (backtrace, gcpro, specbind, etc.) in the Lisp engine. backtrace.h, eval.c: Implement trapping-problems mechanism, eliminate old mechanisms or redo in terms of new one. frame.c, gutter.c: Flush out the concept of "critical display section", defined by the in_display() var. Use an internal_bind() to get it reset, rather than just doing it at end, because there may be a non-local exit. event-msw.c, event-stream.c, console-msw.h, device.c, dialog-msw.c, frame.c, frame.h, intl.c, toolbar.c, menubar-msw.c, redisplay.c, alloc.c, menubar-x.c: Make use of new trapping-errors stuff and rewrite code based on old mechanisms. glyphs-widget.c, redisplay.h: Protect calling Lisp in redisplay. insdel.c: Protect hooks against deleting existing buffers. frame-msw.c: Use EQ, not EQUAL in hash tables whose keys are just numbers. Otherwise we run into stickiness in redisplay because internal_equal() can QUIT. ================================================================ SIGNAL, C-G CHANGES ================================================================ Here we change the way that C-g interacts with event reading. The idea is that a C-g occurring while we're reading a user event should be read as C-g, but elsewhere should be a QUIT. The former code did all sorts of bizarreness -- requiring that no QUIT occurs anywhere in event-reading code (impossible to enforce given the stuff called or Lisp code invoked), and having some weird system involving enqueue/dequeue of a C-g and interaction with Vquit_flag -- and it didn't work. Now, we simply enclose all code where we want C-g read as an event with {begin/end}_dont_check_for_quit(). This completely turns off the mechanism that checks (and may remove or alter) C-g in the read-ahead queues, so we just get the C-g normal. Signal.c documents this very carefully. cmdloop.c: Correct use of dont_check_for_quit to new scheme, remove old out-of-date comments. event-stream.c: Fix C-g handling to actually work. device-x.c: Disable quit checking when err out. signal.c: Cleanup. Add large descriptive comment. process-unix.c, process-nt.c, sysdep.c: Use QUIT instead of REALLY_QUIT. It's not necessary to use REALLY_QUIT and just confuses the issue. lisp.h: Comment quit handlers. ================================================================ CONS CHANGES ================================================================ free_cons() now takes a Lisp_Object not the result of XCONS(). car and cdr have been renamed so that they don't get used directly; go through XCAR(), XCDR() instead. alloc.c, dired.c, editfns.c, emodules.c, fns.c, glyphs-msw.c, glyphs-x.c, glyphs.c, keymap.c, minibuf.c, search.c, eval.c, lread.c, lisp.h: Correct free_cons calling convention: now takes Lisp_Object, not Lisp_Cons chartab.c: Eliminate direct use of ->car, ->cdr, should be black box. callint.c: Rewrote using EXTERNAL_LIST_LOOP to avoid use of Lisp_Cons. ================================================================ USE INTERNAL-BIND-* ================================================================ eval.c: Cleanups of these funs. alloc.c, fileio.c, undo.c, specifier.c, text.c, profile.c, lread.c, redisplay.c, menubar-x.c, macros.c: Rewrote to use internal_bind_int() and internal_bind_lisp_object() in place of whatever varied and cumbersome mechanisms were formerly there. ================================================================ SPECBIND SANITY ================================================================ backtrace.h: - Improved comments backtrace.h, bytecode.c, eval.c: Add new mechanism check_specbind_stack_sanity() for sanity checking code each time the catchlist or specbind stack change. Removed older prototype of same mechanism. ================================================================ MISC ================================================================ lisp.h, insdel.c, window.c, device.c, console.c, buffer.c: Fleshed out authorship. device-msw.c: Correct bad Unicode-ization. print.c: Be more careful when not initialized or in fatal error handling. search.c: Eliminate running_asynch_code, an FSF holdover. alloc.c: Added comments about gc-cons-threshold. dialog-x.c: Use begin_gc_forbidden() around code to build up a widget value tree, like in menubar-x.c. gui.c: Use Qunbound not Qnil as the default for gethash. lisp-disunion.h, lisp-union.h: Added warnings on use of VOID_TO_LISP(). lisp.h: Use ERROR_CHECK_STRUCTURES to turn on ERROR_CHECK_TRAPPING_PROBLEMS and ERROR_CHECK_TYPECHECK lisp.h: Add assert_with_message. lisp.h: Add macros for gcproing entire arrays. (You could do this before but it required manual twiddling the gcpro structure.) lisp.h: Add prototypes for new functions defined elsewhere.
author ben
date Tue, 28 May 2002 08:45:36 +0000
parents a5954632b187
children 79c6ff3eef26
comparison
equal deleted inserted replaced
852:d83885ef293b 853:2b6fa2618f76
1 /* Handling asynchronous signals. 1 /* Handling asynchronous signals.
2 Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. 2 Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
3 Copyright (C) 1995, 1996, 2001 Ben Wing. 3 Copyright (C) 1995, 1996, 2001, 2002 Ben Wing.
4 4
5 This file is part of XEmacs. 5 This file is part of XEmacs.
6 6
7 XEmacs is free software; you can redistribute it and/or modify it 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 8 under the terms of the GNU General Public License as published by the
212 { 212 {
213 kick_status_notify (); 213 kick_status_notify ();
214 } 214 }
215 else 215 else
216 /* call1 GC-protects its arguments */ 216 /* call1 GC-protects its arguments */
217 call1_trapping_errors ("Error in asynchronous timeout callback", 217 call1_trapping_problems ("Error in asynchronous timeout callback",
218 fun, arg); 218 fun, arg, INHIBIT_GC);
219 219
220 waiting_for_user_input_p = 0; 220 waiting_for_user_input_p = 0;
221 221
222 unbind_to (specco); 222 unbind_to (specco);
223 } 223 }
423 /**********************************************************************/ 423 /**********************************************************************/
424 424
425 /* called from QUIT when something_happened gets set (as a result of 425 /* called from QUIT when something_happened gets set (as a result of
426 a signal) */ 426 a signal) */
427 427
428 int 428 void
429 check_what_happened (void) 429 check_what_happened (void)
430 { 430 {
431 #ifdef ERROR_CHECK_TRAPPING_PROBLEMS
432 if (in_display
433 && !((get_inhibit_flags () & INTERNAL_INHIBIT_ERRORS)
434 && (get_inhibit_flags () & INTERNAL_INHIBIT_THROWS)))
435 assert_with_message
436 (0, "QUIT called from within redisplay without being properly wrapped");
437 #endif
438
431 /* No GC can happen anywhere here. handle_async_timeout_signal() 439 /* No GC can happen anywhere here. handle_async_timeout_signal()
432 prevents GC (from asynch timeout handler), so does check_quit() 440 prevents GC (from asynch timeout handler), so does check_quit()
433 (from processing a message such as WM_INITMENU as a result of 441 (from processing a message such as WM_INITMENU as a result of
434 draining the message queue). establish_slow_interrupt_timer() is 442 draining the message queue). establish_slow_interrupt_timer() is
435 too low-level to do anything that might invoke QUIT or call Lisp 443 too low-level to do anything that might invoke QUIT or call Lisp
444 { 452 {
445 slowed_interrupt_timeout_happened = 0; 453 slowed_interrupt_timeout_happened = 0;
446 establish_slow_interrupt_timer (); 454 establish_slow_interrupt_timer ();
447 } 455 }
448 456
449 return check_quit (); 457 check_quit ();
450 } 458 }
451 459
452 #ifdef SIGIO 460 #ifdef SIGIO
453 461
454 /* Signal handler for SIGIO. */ 462 /* Signal handler for SIGIO. */
631 639
632 /**********************************************************************/ 640 /**********************************************************************/
633 /* Control-G checking */ 641 /* Control-G checking */
634 /**********************************************************************/ 642 /**********************************************************************/
635 643
644 /* Note: The code to handle QUIT is divided between lisp.h and signal.c.
645 There is also some special-case code in the async timer code in
646 event-stream.c to notice when the poll-for-quit (and poll-for-sigchld)
647 timers have gone off. */
648
649 /* OK, here's an overview of how this convoluted stuff works:
650
651 [1] Scattered throughout the XEmacs core code are calls to the macro QUIT;
652 This macro checks to see whether a C-g has recently been pressed and
653 not yet handled, and if so, it handles the C-g by calling signal_quit(),
654 which invokes the standard Fsignal() code, with the error being Qquit.
655 Lisp code can establish handlers for this (using condition-case), but
656 normally there is no handler, and so execution is thrown back to the
657 innermost enclosing event loop. (One of the things that happens when
658 entering an event loop is that a condition-case is established that
659 catches *all* calls to `signal', including this one.)
660
661 [2] How does the QUIT macro check to see whether C-g has been pressed;
662 obviously this needs to be extremely fast. Now for some history.
663 In early Lemacs as inherited from the FSF going back 15 years or
664 more, there was a great fondness for using SIGIO (which is sent
665 whenever there is I/O available on a given socket, tty, etc.).
666 In fact, in GNU Emacs, perhaps even today, all reading of events
667 from the X server occurs inside the SIGIO handler! This is crazy,
668 but not completely relevant. What is relevant is that similar
669 stuff happened inside the SIGIO handler for C-g: it searched
670 through all the pending (i.e. not yet delivered to XEmacs yet)
671 X events for one that matched C-g. When it saw a match, it set
672 Vquit_flag to Qt. On TTY's, C-g is actually mapped to be the
673 interrupt character (i.e. it generates SIGINT), and XEmacs's
674 handler for this signal sets Vquit_flag to Qt. Then, sometime
675 later after the signal handlers finished and a QUIT macro was
676 called, the macro noticed the setting of Vquit_flag and used
677 this as an indication to call signal_quit(). What signal_quit()
678 actually does is set Vquit_flag to Qnil (so that we won't get
679 repeated interruptions from a single C-g press) and then calls
680 the equivalent of (signal 'quit nil).
681
682 [3] Another complication is introduced in that Vquit_flag is actually
683 exported to Lisp as `quit-flag'. This allows users some level of
684 control over whether and when C-g is processed as quit, esp. in
685 combination with `inhibit-quit'. This is another Lisp variable,
686 and if set to non-nil, it inhibits signal_quit() from getting
687 called, meaning that the C-g gets essentially ignored. But not
688 completely: Because the resetting of `quit-flag' happens only
689 in signal_quit(), which isn't getting called, the C-g press is
690 still noticed, and as soon as `inhibit-quit' is set back to nil,
691 a quit will be signalled at the next QUIT macro. Thus, what
692 `inhibit-quit' really does is defer quits until after the quit-
693 inhibitted period.
694
695 [4] Another consideration, introduced by XEmacs, is critical quitting.
696 If you press Control-Shift-G instead of just C-g, `quit-flag' is
697 set to `critical' instead of to t. When QUIT processes this value,
698 it *ignores* the value of `inhibit-quit'. This allows you to quit
699 even out of a quit-inhibitted section of code! Furthermore, when
700 signal_quit() notices that it was invoked as a result of a critical
701 quit, it automatically invokes the debugger (which otherwise would
702 only happen when `debug-on-quit' is set to t).
703
704 [5] Well, I explained above about how `quit-flag' gets set correctly,
705 but I began with a disclaimer stating that this was the old way
706 of doing things. What's done now? Well, first of all, the SIGIO
707 handler (which formerly checked all pending events to see if there's
708 a C-g) now does nothing but set a flag -- or actually two flags,
709 something_happened and quit_check_signal_happened. There are two
710 flags because the QUIT macro is now used for more than just handling
711 QUIT; it's also used for running asynchronous timeout handlers that
712 have recently expired, and perhaps other things. The idea here is
713 that the QUIT macros occur extremely often in the code, but only occur
714 at places that are relatively safe -- in particular, if an error occurs,
715 nothing will get completely trashed.
716
717 [6] Now, let's look at QUIT again.
718
719 UNFINISHED. Note, however, that as of the point when this comment
720 got committed to CVS (mid-2001), the interaction between reading
721 C-g as an event and processing it as QUIT was overhauled to (for
722 the first time) be understandable and actually work correctly.
723 Now, the way things work is that if C-g is pressed while XEmacs is
724 blocking at the top level, waiting for a user event, it will be
725 read as an event; otherwise, it will cause QUIT. (This includes
726 times when XEmacs is blocking, but not waiting for a user event,
727 e.g. accept-process-output and wait_delaying_user_events().)
728 Formerly, this was supposed to happen, but didn't always due to a
729 bizarre and broken scheme, documented in next_event_internal
730 like this:
731
732 If we read a ^G, then set quit-flag but do not discard the ^G.
733 The callers of next_event_internal() will do one of two things:
734
735 -- set Vquit_flag to Qnil. (next-event does this.) This will
736 cause the ^G to be treated as a normal keystroke.
737 -- not change Vquit_flag but attempt to enqueue the ^G, at
738 which point it will be discarded. The next time QUIT is
739 called, it will notice that Vquit_flag was set.
740
741 This required weirdness in enqueue_command_event_1 like this:
742
743 put the event on the typeahead queue, unless
744 the event is the quit char, in which case the `QUIT'
745 which will occur on the next trip through this loop is
746 all the processing we should do - leaving it on the queue
747 would cause the quit to be processed twice.
748
749 And further weirdness elsewhere, none of which made any sense,
750 and didn't work, because (e.g.) it required that QUIT never
751 happen anywhere inside next_event_internal() or any callers when
752 C-g should be read as a user event, which was impossible to
753 implement in practice.
754
755 Now what we do is fairly simple. Callers of next_event_internal()
756 that want C-g read as a user event call begin_dont_check_for_quit().
757 next_event_internal(), when it gets a C-g, simply sets Vquit_flag
758 (just as when a C-g is detected during the operation of QUIT or
759 QUITP), and then tries to QUIT. This will fail if blocked by the
760 previous call, at which point next_event_internal() will return
761 the C-g as an event. To unblock things, first set Vquit_flag to
762 nil (it was set to t when the C-g was read, and if we don't reset
763 it, the next call to QUIT will quit), and then unbind_to() the
764 depth returned by begin_dont_check_for_quit(). It makes no
765 difference is QUIT is called a zillion times in next_event_internal()
766 or anywhere else, because it's blocked and will never signal.
767
768 --ben
769 */
770
771
636 static Lisp_Object 772 static Lisp_Object
637 restore_dont_check_for_quit (Lisp_Object val) 773 restore_dont_check_for_quit (Lisp_Object val)
638 { 774 {
639 dont_check_for_quit = XINT (val); 775 dont_check_for_quit = XINT (val);
640 return Qnil; 776 return Qnil;
652 /* As an optimization in QUIT_FLAG_SAYS_SHOULD_QUIT, we bind inhibit-quit 788 /* As an optimization in QUIT_FLAG_SAYS_SHOULD_QUIT, we bind inhibit-quit
653 to t -- it has to be checked anyway, and by doing this, we only need 789 to t -- it has to be checked anyway, and by doing this, we only need
654 to check dont_check_for_quit when quit-flag == `critical', which is 790 to check dont_check_for_quit when quit-flag == `critical', which is
655 rare. */ 791 rare. */
656 specbind (Qinhibit_quit, Qt); 792 specbind (Qinhibit_quit, Qt);
657 record_unwind_protect (restore_dont_check_for_quit, 793 internal_bind_int (&dont_check_for_quit, 1);
658 make_int (dont_check_for_quit));
659 dont_check_for_quit = 1;
660 794
661 return depth; 795 return depth;
662 } 796 }
663 797
664 /* The effect of this function is to set Vquit_flag if the user pressed 798 /* If we're inside of a begin_dont_check_for_quit() section, but want
665 ^G and discard the ^G, so as to not notice the same ^G again. */ 799 to temporarily enable quit-checking, call this. This is used in
800 particular when processing menu filters -- some menu filters do
801 antisocial things like load large amounts of Lisp code (custom in
802 particular), and we obviously want a way of breaking out of any
803 problems. If you do use this, you should really be trapping the
804 throw() that comes from the quitting (as does the code that handles
805 menus popping up). */
806
666 int 807 int
808 begin_do_check_for_quit (void)
809 {
810 int depth = specpdl_depth ();
811 specbind (Qinhibit_quit, Qnil);
812 internal_bind_int (&dont_check_for_quit, 0);
813 /* #### should we set Vquit_flag to Qnil? */
814 return depth;
815 }
816
817 /* The effect of this function is to set Vquit_flag appropriately if the
818 user pressed C-g or Sh-C-g. After this function finishes, Vquit_flag
819 will be Qt for C-g, Qcritical for Sh-C-g, and unchanged otherwise.
820 The C-g or Sh-C-g is discarded, so it won't be noticed again.
821 */
822
823 void
667 check_quit (void) 824 check_quit (void)
668 { 825 {
669 /* dont_check_for_quit is set in two circumstances: 826 /* dont_check_for_quit is set in three circumstances:
670 827
671 (1) when we are in the process of changing the window 828 (1) when we are in the process of changing the window
672 configuration. The frame might be in an inconsistent state, 829 configuration. The frame might be in an inconsistent state,
673 which will cause assertion failures if we check for QUIT. 830 which will cause assertion failures if we check for QUIT.
674 831
675 (2) when we are reading events, and want to read the C-g 832 (2) when we are reading events, and want to read the C-g
676 as an event. The normal check for quit will discard the C-g, 833 as an event. The normal check for quit will discard the C-g,
677 which would be bad. 834 which would be bad.
678 835
679 [[#### C-g is still often read as quit, e.g. if you type C-x C-g (the 836 (3) when we're going down with a fatal error. we're most likely
680 C-g happens during the sit-for in maybe_echo_keys(); even if we 837 in an inconsistent state, and we definitely don't want to be
681 attempt to inhibit quit here, there is still a check later on for 838 interrupted. */
682 QUIT. To fix this properly requires a fairly substantial overhaul of 839
683 the quit-checking code, which is probably not worth it.)]] not true, 840 /* We should *not* conditionalize on Vinhibit_quit, or
684 we just have to always do dont_check_for_quit around all code that
685 reads events. my stderr-proc ws already does this.
686
687 We should *not* conditionalize on Vinhibit_quit, or
688 critical-quit (Control-Shift-G) won't work right. */ 841 critical-quit (Control-Shift-G) won't work right. */
689 842
690 /* WARNING: Even calling check_quit(), without actually dispatching 843 /* WARNING: Even calling check_quit(), without actually dispatching
691 a quit signal, can result in arbitrary Lisp code getting executed 844 a quit signal, can result in arbitrary Lisp code getting executed
692 -- at least under Windows. (Not to mention obvious Lisp 845 -- at least under Windows. (Not to mention obvious Lisp
822 XEMACS! mainCRTStartup + 180 bytes 975 XEMACS! mainCRTStartup + 180 bytes
823 _start() line 171 976 _start() line 171
824 KERNEL32! BaseProcessStart@4 + 115547 bytes 977 KERNEL32! BaseProcessStart@4 + 115547 bytes
825 978
826 */ 979 */
827 980 int specdepth;
981
828 if (dont_check_for_quit) 982 if (dont_check_for_quit)
829 return 0; 983 return;
830 984
831 if (quit_check_signal_happened) 985 if (quit_check_signal_happened)
832 { 986 {
833 /* Since arbitrary Lisp code may be executed, GC might happen, 987 /* Since arbitrary Lisp code may be executed, GC might happen,
834 which would majorly fuck a lot of things, e.g. re_match() 988 which would majorly fuck a lot of things, e.g. re_match()
835 [string gets relocated] and lots of other code that's not 989 [string gets relocated] and lots of other code that's not
836 prepared to handle GC in QUIT. */ 990 prepared to handle GC in QUIT. */
837 int specdepth = begin_gc_forbidden (); 991 specdepth = begin_gc_forbidden ();
838 quit_check_signal_happened = 0; 992 quit_check_signal_happened = 0;
839 event_stream_quit_p (); 993 event_stream_quit_p ();
840 unbind_to (specdepth); 994 unbind_to (specdepth);
841 return 1; 995 }
842 }
843 else
844 return 0;
845 } 996 }
846 997
847 998
848 999
849 void 1000 void
878 #endif /* not SIGIO and not DONT_POLL_FOR_QUIT */ 1029 #endif /* not SIGIO and not DONT_POLL_FOR_QUIT */
879 } 1030 }
880 1031
881 #endif /* 0 */ 1032 #endif /* 0 */
882 1033
883 #if defined(HAVE_UNIX_PROCESSES) && !defined(SIGCHLD) 1034 #if defined (HAVE_UNIX_PROCESSES) && !defined (SIGCHLD)
884 1035
885 static void 1036 static void
886 init_poll_for_sigchld (void) 1037 init_poll_for_sigchld (void)
887 { 1038 {
888 /* Check for terminated processes every 1/4 of a second. 1039 /* Check for terminated processes every 1/4 of a second.
1063 #elif !defined (DONT_POLL_FOR_QUIT) 1214 #elif !defined (DONT_POLL_FOR_QUIT)
1064 init_poll_for_quit (); 1215 init_poll_for_quit ();
1065 #endif 1216 #endif
1066 } 1217 }
1067 1218
1068 #if defined(HAVE_UNIX_PROCESSES) && !defined(SIGCHLD) 1219 #if defined (HAVE_UNIX_PROCESSES) && !defined (SIGCHLD)
1069 init_poll_for_sigchld (); 1220 init_poll_for_sigchld ();
1070 #endif 1221 #endif
1071 1222
1072 EMACS_UNBLOCK_ALL_SIGNALS (); 1223 EMACS_UNBLOCK_ALL_SIGNALS ();
1073 1224