* src/eval.c: Add `inhibit-debugger'.
[bpt/emacs.git] / src / keyboard.c
index ff2b75e..8091258 100644 (file)
@@ -21,7 +21,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #define KEYBOARD_INLINE EXTERN_INLINE
 
-#include <signal.h>
 #include <stdio.h>
 #include <setjmp.h>
 #include "lisp.h"
@@ -449,9 +448,8 @@ static void restore_getcjmp (jmp_buf);
 static Lisp_Object apply_modifiers (int, Lisp_Object);
 static void clear_event (struct input_event *);
 static Lisp_Object restore_kboard_configuration (Lisp_Object);
-static void interrupt_signal (int signalnum);
 #ifdef SIGIO
-static void input_available_signal (int signo);
+static void deliver_input_available_signal (int signo);
 #endif
 static void handle_interrupt (void);
 static _Noreturn void quit_throw_to_read_char (int);
@@ -459,7 +457,7 @@ static void process_special_events (void);
 static void timer_start_idle (void);
 static void timer_stop_idle (void);
 static void timer_resume_idle (void);
-static void handle_user_signal (int);
+static void deliver_user_signal (int);
 static char *find_user_signal_name (int);
 static int store_user_signal_events (void);
 
@@ -1023,7 +1021,7 @@ restore_kboard_configuration (Lisp_Object was_locked)
       pop_kboard ();
       /* The pop should not change the kboard.  */
       if (single_kboard && current_kboard != prev)
-        abort ();
+        emacs_abort ();
     }
   return Qnil;
 }
@@ -1315,7 +1313,7 @@ usage: (track-mouse BODY...)  */)
    If ignore_mouse_drag_p is non-zero, ignore (implicit) mouse movement
    after resizing the tool-bar window.  */
 
-#if !defined HAVE_WINDOW_SYSTEM
+#if !defined HAVE_WINDOW_SYSTEM || defined USE_GTK || defined HAVE_NS
 static
 #endif
 int ignore_mouse_drag_p;
@@ -2605,13 +2603,13 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
            Lisp_Object last = KVAR (kb, kbd_queue);
            /* We shouldn't get here if we were in single-kboard mode!  */
            if (single_kboard)
-             abort ();
+             emacs_abort ();
            if (CONSP (last))
              {
                while (CONSP (XCDR (last)))
                  last = XCDR (last);
                if (!NILP (XCDR (last)))
-                 abort ();
+                 emacs_abort ();
              }
            if (!CONSP (last))
              kset_kbd_queue (kb, Fcons (c, Qnil));
@@ -2784,7 +2782,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
       if (current_kboard->kbd_queue_has_data)
        {
          if (!CONSP (KVAR (current_kboard, kbd_queue)))
-           abort ();
+           emacs_abort ();
          c = XCAR (KVAR (current_kboard, kbd_queue));
          kset_kbd_queue (current_kboard,
                          XCDR (KVAR (current_kboard, kbd_queue)));
@@ -2851,7 +2849,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
              while (CONSP (XCDR (last)))
                last = XCDR (last);
              if (!NILP (XCDR (last)))
-               abort ();
+               emacs_abort ();
            }
          if (!CONSP (last))
            kset_kbd_queue (kb, Fcons (c, Qnil));
@@ -3560,7 +3558,7 @@ kbd_buffer_store_event_hold (register struct input_event *event,
                             struct input_event *hold_quit)
 {
   if (event->kind == NO_EVENT)
-    abort ();
+    emacs_abort ();
 
   if (hold_quit && hold_quit->kind != NO_EVENT)
     return;
@@ -3604,7 +3602,7 @@ kbd_buffer_store_event_hold (register struct input_event *event,
 
          if (hold_quit)
            {
-             memcpy (hold_quit, event, sizeof (*event));
+             *hold_quit = *event;
              return;
            }
 
@@ -3681,7 +3679,7 @@ kbd_buffer_store_event_hold (register struct input_event *event,
       if (immediate_quit && NILP (Vinhibit_quit))
        {
          immediate_quit = 0;
-         sigfree ();
+         pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
          QUIT;
        }
     }
@@ -3833,7 +3831,11 @@ kbd_buffer_get_event (KBOARD **kbp,
       unhold_keyboard_input ();
 #ifdef SIGIO
       if (!noninteractive)
-        signal (SIGIO, input_available_signal);
+       {
+         struct sigaction action;
+         emacs_sigaction_init (&action, deliver_input_available_signal);
+         sigaction (SIGIO, &action, 0);
+       }
 #endif /* SIGIO */
       start_polling ();
     }
@@ -3955,7 +3957,7 @@ kbd_buffer_get_event (KBOARD **kbp,
 #else
          /* We're getting selection request events, but we don't have
              a window system.  */
-         abort ();
+         emacs_abort ();
 #endif
        }
 
@@ -4131,7 +4133,7 @@ kbd_buffer_get_event (KBOARD **kbp,
                *used_mouse_menu = 1;
 #endif
 #ifdef HAVE_NS
-             /* certain system events are non-key events */
+             /* Certain system events are non-key events.  */
              if (used_mouse_menu
                   && event->kind == NS_NONKEY_EVENT)
                *used_mouse_menu = 1;
@@ -4159,7 +4161,7 @@ kbd_buffer_get_event (KBOARD **kbp,
         so x remains nil.  */
       x = Qnil;
 
-      /* XXX Can f or mouse_position_hook be NULL here? */
+      /* XXX Can f or mouse_position_hook be NULL here?  */
       if (f && FRAME_TERMINAL (f)->mouse_position_hook)
         (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, 0, &bar_window,
                                                     &part, &x, &y, &t);
@@ -4192,7 +4194,7 @@ kbd_buffer_get_event (KBOARD **kbp,
   else
     /* We were promised by the above while loop that there was
        something for us to read!  */
-    abort ();
+    emacs_abort ();
 
   input_pending = readable_events (0);
 
@@ -4261,7 +4263,7 @@ process_special_events (void)
 #else
          /* We're getting selection request events, but we don't have
              a window system.  */
-         abort ();
+         emacs_abort ();
 #endif
        }
     }
@@ -5614,7 +5616,7 @@ make_lispy_event (struct input_event *event)
          else if (FRAMEP (event->frame_or_window))
            f = XFRAME (event->frame_or_window);
          else
-           abort ();
+           emacs_abort ();
 
          if (FRAME_WINDOW_P (f))
            fuzz = double_click_fuzz;
@@ -5721,7 +5723,7 @@ make_lispy_event (struct input_event *event)
        else
          /* Every mouse event should either have the down_modifier or
              the up_modifier set.  */
-         abort ();
+         emacs_abort ();
 
        {
          /* Get the symbol we should use for the mouse click.  */
@@ -5782,7 +5784,7 @@ make_lispy_event (struct input_event *event)
          else if (FRAMEP (event->frame_or_window))
            fr = XFRAME (event->frame_or_window);
          else
-           abort ();
+           emacs_abort ();
 
          fuzz = FRAME_WINDOW_P (fr)
            ? double_click_fuzz : double_click_fuzz / 8;
@@ -5802,7 +5804,7 @@ make_lispy_event (struct input_event *event)
          else
            /* Every wheel event should either have the down_modifier or
               the up_modifier set.  */
-           abort ();
+           emacs_abort ();
 
           if (event->kind == HORIZ_WHEEL_EVENT)
             symbol_num += 2;
@@ -5971,7 +5973,7 @@ make_lispy_event (struct input_event *event)
       {
        char *name = find_user_signal_name (event->code);
        if (!name)
-         abort ();
+         emacs_abort ();
        return intern (name);
       }
 
@@ -6052,7 +6054,7 @@ make_lispy_event (struct input_event *event)
 
       /* The 'kind' field of the event is something we don't recognize.  */
     default:
-      abort ();
+      emacs_abort ();
     }
 }
 
@@ -6229,7 +6231,7 @@ apply_modifiers_uncached (int modifiers, char *base, int base_len, int base_len_
     /* Only the event queue may use the `up' modifier; it should always
        be turned into a click or drag event before presented to lisp code.  */
     if (modifiers & up_modifier)
-      abort ();
+      emacs_abort ();
 
     if (modifiers & alt_modifier)   { *p++ = 'A'; *p++ = '-'; }
     if (modifiers & ctrl_modifier)  { *p++ = 'C'; *p++ = '-'; }
@@ -6324,7 +6326,7 @@ parse_modifiers (Lisp_Object symbol)
                            Qnil);
 
       if (modifiers & ~INTMASK)
-       abort ();
+       emacs_abort ();
       XSETFASTINT (mask, modifiers);
       elements = Fcons (unmodified, Fcons (mask, Qnil));
 
@@ -6781,10 +6783,12 @@ gobble_input (int expected)
 #ifdef SIGIO
   if (interrupt_input)
     {
-      SIGMASKTYPE mask;
-      mask = sigblock (sigmask (SIGIO));
+      sigset_t blocked, procmask;
+      sigemptyset (&blocked);
+      sigaddset (&blocked, SIGIO);
+      pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
       read_avail_input (expected);
-      sigsetmask (mask);
+      pthread_sigmask (SIG_SETMASK, &procmask, 0);
     }
   else
 #ifdef POLL_FOR_INPUT
@@ -6793,10 +6797,12 @@ gobble_input (int expected)
      it's always set.  */
   if (!interrupt_input && poll_suppress_count == 0)
     {
-      SIGMASKTYPE mask;
-      mask = sigblock (sigmask (SIGALRM));
+      sigset_t blocked, procmask;
+      sigemptyset (&blocked);
+      sigaddset (&blocked, SIGALRM);
+      pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
       read_avail_input (expected);
-      sigsetmask (mask);
+      pthread_sigmask (SIG_SETMASK, &procmask, 0);
     }
   else
 #endif
@@ -6832,10 +6838,12 @@ record_asynch_buffer_change (void)
 #ifdef SIGIO
   if (interrupt_input)
     {
-      SIGMASKTYPE mask;
-      mask = sigblock (sigmask (SIGIO));
+      sigset_t blocked, procmask;
+      sigemptyset (&blocked);
+      sigaddset (&blocked, SIGIO);
+      pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
       kbd_buffer_store_event (&event);
-      sigsetmask (mask);
+      pthread_sigmask (SIG_SETMASK, &procmask, 0);
     }
   else
 #endif
@@ -7001,7 +7009,7 @@ tty_read_avail_input (struct terminal *terminal,
 
   if (terminal->type != output_termcap
       && terminal->type != output_msdos_raw)
-    abort ();
+    emacs_abort ();
 
   /* XXX I think the following code should be moved to separate hook
      functions in system-dependent files.  */
@@ -7236,12 +7244,8 @@ process_pending_signals (void)
 /* Note SIGIO has been undef'd if FIONREAD is missing.  */
 
 static void
-input_available_signal (int signo)
+handle_input_available_signal (int sig)
 {
-  /* Must preserve main program's value of errno.  */
-  int old_errno = errno;
-  SIGNAL_THREAD_CHECK (signo);
-
 #ifdef SYNC_INPUT
   interrupt_input_pending = 1;
   pending_signals = 1;
@@ -7253,8 +7257,12 @@ input_available_signal (int signo)
 #ifndef SYNC_INPUT
   handle_async_input ();
 #endif
+}
 
-  errno = old_errno;
+static void
+deliver_input_available_signal (int sig)
+{
+  handle_on_main_thread (sig, handle_input_available_signal);
 }
 #endif /* SIGIO */
 
@@ -7296,6 +7304,7 @@ static struct user_signal_info *user_signals = NULL;
 void
 add_user_signal (int sig, const char *name)
 {
+  struct sigaction action;
   struct user_signal_info *p;
 
   for (p = user_signals; p; p = p->next)
@@ -7310,18 +7319,16 @@ add_user_signal (int sig, const char *name)
   p->next = user_signals;
   user_signals = p;
 
-  signal (sig, handle_user_signal);
+  emacs_sigaction_init (&action, deliver_user_signal);
+  sigaction (sig, &action, 0);
 }
 
 static void
 handle_user_signal (int sig)
 {
-  int old_errno = errno;
   struct user_signal_info *p;
   const char *special_event_name = NULL;
 
-  SIGNAL_THREAD_CHECK (sig);
-
   if (SYMBOLP (Vdebug_on_event))
     special_event_name = SSDATA (SYMBOL_NAME (Vdebug_on_event));
 
@@ -7355,8 +7362,12 @@ handle_user_signal (int sig)
          }
        break;
       }
+}
 
-  errno = old_errno;
+static void
+deliver_user_signal (int sig)
+{
+  handle_on_main_thread (sig, handle_user_signal);
 }
 
 static char *
@@ -7381,7 +7392,7 @@ store_user_signal_events (void)
   for (p = user_signals; p; p = p->next)
     if (p->npending > 0)
       {
-       SIGMASKTYPE mask;
+       sigset_t blocked, procmask;
 
        if (nstored == 0)
          {
@@ -7391,7 +7402,10 @@ store_user_signal_events (void)
          }
        nstored += p->npending;
 
-       mask = sigblock (sigmask (p->sig));
+       sigemptyset (&blocked);
+       sigaddset (&blocked, p->sig);
+       pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
+
        do
          {
            buf.code = p->sig;
@@ -7399,7 +7413,8 @@ store_user_signal_events (void)
            p->npending--;
          }
        while (p->npending > 0);
-       sigsetmask (mask);
+
+       pthread_sigmask (SIG_SETMASK, &procmask, 0);
       }
 
   return nstored;
@@ -10776,17 +10791,10 @@ clear_waiting_for_input (void)
    Otherwise, tell QUIT to kill Emacs.  */
 
 static void
-interrupt_signal (int signalnum)       /* If we don't have an argument, some */
-                                       /* compilers complain in signal calls.  */
+handle_interrupt_signal (int sig)
 {
-  /* Must preserve main program's value of errno.  */
-  int old_errno = errno;
-  struct terminal *terminal;
-
-  SIGNAL_THREAD_CHECK (signalnum);
-
   /* See if we have an active terminal on our controlling tty.  */
-  terminal = get_named_tty ("/dev/tty");
+  struct terminal *terminal = get_named_tty ("/dev/tty");
   if (!terminal)
     {
       /* If there are no frames there, let's pretend that we are a
@@ -10807,10 +10815,15 @@ interrupt_signal (int signalnum)      /* If we don't have an argument, some */
 
       handle_interrupt ();
     }
+}
 
-  errno = old_errno;
+static void
+deliver_interrupt_signal (int sig)
+{
+  handle_on_main_thread (sig, handle_interrupt_signal);
 }
 
+
 /* If Emacs is stuck because `inhibit-quit' is true, then keep track
    of the number of times C-g has been requested.  If C-g is pressed
    enough times, then quit anyway.  See bug#6585.  */
@@ -10840,7 +10853,10 @@ handle_interrupt (void)
       /* If SIGINT isn't blocked, don't let us be interrupted by
         another SIGINT, it might be harmful due to non-reentrancy
         in I/O functions.  */
-      sigblock (sigmask (SIGINT));
+      sigset_t blocked;
+      sigemptyset (&blocked);
+      sigaddset (&blocked, SIGINT);
+      pthread_sigmask (SIG_BLOCK, &blocked, 0);
 
       fflush (stdout);
       reset_all_sys_modes ();
@@ -10902,7 +10918,7 @@ handle_interrupt (void)
 #endif /* not MSDOS */
       fflush (stdout);
       if (((c = getchar ()) & ~040) == 'Y')
-       abort ();
+       emacs_abort ();
       while (c != '\n') c = getchar ();
 #ifdef MSDOS
       printf ("\r\nContinuing...\r\n");
@@ -10911,7 +10927,7 @@ handle_interrupt (void)
 #endif /* not MSDOS */
       fflush (stdout);
       init_all_sys_modes ();
-      sigfree ();
+      pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
     }
   else
     {
@@ -10924,7 +10940,7 @@ handle_interrupt (void)
          struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
 
          immediate_quit = 0;
-          sigfree ();
+         pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
          saved = gl_state;
          GCPRO4 (saved.object, saved.global_code,
                  saved.current_syntax_table, saved.old_prop);
@@ -10969,7 +10985,7 @@ quit_throw_to_read_char (int from_signal)
   if (!from_signal && EQ (Vquit_flag, Qkill_emacs))
     Fkill_emacs (Qnil);
 
-  sigfree ();
+  pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
   /* Prevent another signal from doing this before we finish.  */
   clear_waiting_for_input ();
   input_pending = 0;
@@ -10983,7 +10999,7 @@ quit_throw_to_read_char (int from_signal)
 #ifdef POLL_FOR_INPUT
   /* May be > 1 if in recursive minibuffer.  */
   if (poll_suppress_count == 0)
-    abort ();
+    emacs_abort ();
 #endif
 #endif
   if (FRAMEP (internal_last_event_frame)
@@ -11341,7 +11357,7 @@ delete_kboard (KBOARD *kb)
 
   for (kbp = &all_kboards; *kbp != kb; kbp = &(*kbp)->next_kboard)
     if (*kbp == NULL)
-      abort ();
+      emacs_abort ();
   *kbp = kb->next_kboard;
 
   /* Prevent a dangling reference to KB.  */
@@ -11352,7 +11368,7 @@ delete_kboard (KBOARD *kb)
       current_kboard = FRAME_KBOARD (XFRAME (selected_frame));
       single_kboard = 0;
       if (current_kboard == kb)
-       abort ();
+       emacs_abort ();
     }
 
   wipe_kboard (kb);
@@ -11404,17 +11420,23 @@ init_keyboard (void)
          SIGINT.  There is special code in interrupt_signal to exit
          Emacs on SIGINT when there are no termcap frames on the
          controlling terminal.  */
-      signal (SIGINT, interrupt_signal);
+      struct sigaction action;
+      emacs_sigaction_init (&action, deliver_interrupt_signal);
+      sigaction (SIGINT, &action, 0);
 #ifndef DOS_NT
       /* For systems with SysV TERMIO, C-g is set up for both SIGINT and
         SIGQUIT and we can't tell which one it will give us.  */
-      signal (SIGQUIT, interrupt_signal);
+      sigaction (SIGQUIT, &action, 0);
 #endif /* not DOS_NT */
     }
 /* Note SIGIO has been undef'd if FIONREAD is missing.  */
 #ifdef SIGIO
   if (!noninteractive)
-    signal (SIGIO, input_available_signal);
+    {
+      struct sigaction action;
+      emacs_sigaction_init (&action, deliver_input_available_signal);
+      sigaction (SIGIO, &action, 0);
+    }
 #endif /* SIGIO */
 
 /* Use interrupt input by default, if it works and noninterrupt input
@@ -11426,7 +11448,7 @@ init_keyboard (void)
   interrupt_input = 0;
 #endif
 
-  sigfree ();
+  pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
   dribble = 0;
 
   if (keyboard_init_hook)