Merge from emacs-24; up to 2012-05-07T14:57:18Z!michael.albinus@gmx.de
[bpt/emacs.git] / src / emacs.c
index adfff6f..d4b52ab 100644 (file)
@@ -20,13 +20,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 #include <config.h>
-#include <signal.h>
 #include <errno.h>
 #include <stdio.h>
 
 #include <sys/types.h>
 #include <sys/file.h>
-#include <setjmp.h>
 #include <unistd.h>
 
 #include "lisp.h"
@@ -90,15 +88,15 @@ extern void moncontrol (int mode);
 #endif
 
 static const char emacs_version[] = VERSION;
-static const char emacs_copyright[] = "Copyright (C) 2012 Free Software Foundation, Inc.";
+static const char emacs_copyright[] = COPYRIGHT;
 
 /* Empty lisp strings.  To avoid having to build any others.  */
 Lisp_Object empty_unibyte_string, empty_multibyte_string;
 
-/* Set nonzero after Emacs has started up the first time.
-  Prevents reinitialization of the Lisp world and keymaps
-  on subsequent starts.  */
-int initialized;
+/* Set after Emacs has started up the first time.
+   Prevents reinitialization of the Lisp world and keymaps
+   on subsequent starts.  */
+bool initialized;
 
 #ifdef DARWIN_OS
 extern void unexec_init_emacs_zone (void);
@@ -112,9 +110,9 @@ static void *malloc_state_ptr;
 extern void *malloc_get_state (void);
 /* From glibc, a routine that overwrites the malloc internal state.  */
 extern int malloc_set_state (void*);
-/* Non-zero if the MALLOC_CHECK_ environment variable was set while
+/* True if the MALLOC_CHECK_ environment variable was set while
    dumping.  Used to work around a bug in glibc's malloc.  */
-static int malloc_using_checking;
+static bool malloc_using_checking;
 #endif
 
 Lisp_Object Qfile_name_handler_alist;
@@ -123,17 +121,17 @@ Lisp_Object Qrisky_local_variable;
 
 Lisp_Object Qkill_emacs;
 
-/* If non-zero, Emacs should not attempt to use a window-specific code,
+/* If true, Emacs should not attempt to use a window-specific code,
    but instead should use the virtual terminal under which it was started.  */
-int inhibit_window_system;
+bool inhibit_window_system;
 
-/* If non-zero, a filter or a sentinel is running.  Tested to save the match
+/* If true, a filter or a sentinel is running.  Tested to save the match
    data on the first attempt to change it inside asynchronous code.  */
-int running_asynch_code;
+bool running_asynch_code;
 
 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NS)
-/* If non-zero, -d was specified, meaning we're using some window system.  */
-int display_arg;
+/* If true, -d was specified, meaning we're using some window system.  */
+bool display_arg;
 #endif
 
 /* An address near the bottom of the stack.
@@ -150,11 +148,11 @@ static void *my_heap_start;
 static uprintmax_t heap_bss_diff;
 #endif
 
-/* Nonzero means running Emacs without interactive terminal.  */
-int noninteractive;
+/* True means running Emacs without interactive terminal.  */
+bool noninteractive;
 
-/* Nonzero means remove site-lisp directories from load-path.  */
-int no_site_lisp;
+/* True means remove site-lisp directories from load-path.  */
+bool no_site_lisp;
 
 /* Name for the server started by the daemon.*/
 static char *daemon_name;
@@ -272,16 +270,8 @@ section of the Emacs manual or the file BUGS.\n"
 /* Signal code for the fatal signal that was received.  */
 static int fatal_error_code;
 
-/* Nonzero if handling a fatal error already.  */
-int fatal_error_in_progress;
-
-#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
-/* When compiled with GTK and running under Gnome,
-   multiple threads may be created.  Keep track of our main
-   thread to make sure signals are delivered to it (see syssignal.h).  */
-
-pthread_t main_thread;
-#endif
+/* True if handling a fatal error already.  */
+bool fatal_error_in_progress;
 
 #ifdef HAVE_NS
 /* NS autrelease pool, for memory management.  */
@@ -291,13 +281,23 @@ static void *ns_pool;
 
 
 /* Handle bus errors, invalid instruction, etc.  */
-#ifndef FLOAT_CATCH_SIGILL
-static
-#endif
-void
-fatal_error_signal (int sig)
+static void
+handle_fatal_signal (int sig)
+{
+  fatal_error_backtrace (sig, 10);
+}
+
+static void
+deliver_fatal_signal (int sig)
+{
+  handle_on_main_thread (sig, handle_fatal_signal);
+}
+
+/* Report a fatal error due to signal SIG, output a backtrace of at
+   most BACKTRACE_LIMIT lines, and exit.  */
+_Noreturn void
+fatal_error_backtrace (int sig, int backtrace_limit)
 {
-  SIGNAL_THREAD_CHECK (sig);
   fatal_error_code = sig;
   signal (sig, SIG_DFL);
 
@@ -311,7 +311,8 @@ fatal_error_signal (int sig)
       if (sig == SIGTERM || sig == SIGHUP || sig == SIGINT)
         Fkill_emacs (make_number (sig));
 
-      shut_down_emacs (sig, 0, Qnil);
+      shut_down_emacs (sig, Qnil);
+      emacs_backtrace (backtrace_limit);
     }
 
   /* Signal the same code; this time it will really be fatal.
@@ -319,43 +320,44 @@ fatal_error_signal (int sig)
      going to send is probably blocked, so we have to unblock it if we
      want to really receive it.  */
 #ifndef MSDOS
-  sigunblock (sigmask (fatal_error_code));
+  {
+    sigset_t unblocked;
+    sigemptyset (&unblocked);
+    sigaddset (&unblocked, fatal_error_code);
+    pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
+  }
 #endif
 
   kill (getpid (), fatal_error_code);
+
+  /* This shouldn't be executed, but it prevents a warning.  */
+  exit (1);
 }
 
 #ifdef SIGDANGER
 
 /* Handler for SIGDANGER.  */
-void
-memory_warning_signal (int sig)
+static void deliver_danger_signal (int);
+
+static void
+handle_danger_signal (int sig)
 {
-  signal (sig, memory_warning_signal);
-  SIGNAL_THREAD_CHECK (sig);
+  struct sigaction action;
+  emacs_sigaction_init (&action, deliver_danger_signal);
+  sigaction (sig, &action, 0);
 
   malloc_warning ("Operating system warns that virtual memory is running low.\n");
 
   /* It might be unsafe to call do_auto_save now.  */
   force_auto_save_soon ();
 }
-#endif
-
-/* We define abort, rather than using it from the library,
-   so that GDB can return from a breakpoint here.
-   MSDOS has its own definition in msdos.c.  */
 
-#if ! defined (DOS_NT) && ! defined (NO_ABORT)
-
-void
-abort (void)
+static void
+deliver_danger_signal (int sig)
 {
-  kill (getpid (), SIGABRT);
-  /* This shouldn't be executed, but it prevents a warning.  */
-  exit (1);
+  handle_on_main_thread (sig, handle_danger_signal);
 }
 #endif
-
 \f
 /* Code for dealing with Lisp access to the Unix command line.  */
 
@@ -568,7 +570,7 @@ DEFINE_DUMMY_FUNCTION (__main)
    Too bad we can't just use getopt for all of this, but we don't have
    enough information to do it right.  */
 
-static int
+static bool
 argmatch (char **argv, int argc, const char *sstr, const char *lstr,
           int minlen, char **valptr, int *skipptr)
 {
@@ -675,18 +677,19 @@ main (int argc, char **argv)
   Lisp_Object dummy;
 #endif
   char stack_bottom_variable;
-  int do_initial_setlocale;
+  bool do_initial_setlocale;
   int skip_args = 0;
 #ifdef HAVE_SETRLIMIT
   struct rlimit rlim;
 #endif
-  int no_loadup = 0;
+  bool no_loadup = 0;
   char *junk = 0;
   char *dname_arg = 0;
 #ifdef NS_IMPL_COCOA
   char dname_arg2[80];
 #endif
   char *ch_to_dir;
+  struct sigaction fatal_error_action;
 
 #if GC_MARK_STACK
   stack_base = &dummy;
@@ -845,20 +848,12 @@ main (int argc, char **argv)
   /* Arrange to get warning messages as memory fills up.  */
   memory_warnings (0, malloc_warning);
 
-  /* Call malloc at least once, to run the initial __malloc_hook.
+  /* Call malloc at least once, to run malloc_initialize_hook.
      Also call realloc and free for consistency.  */
   free (realloc (malloc (4), 4));
 
-# ifndef SYNC_INPUT
-  /* Arrange to disable interrupt input inside malloc etc.  */
-  uninterrupt_malloc ();
-# endif /* not SYNC_INPUT */
 #endif /* not SYSTEM_MALLOC */
 
-#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
-  main_thread = pthread_self ();
-#endif /* FORWARD_SIGNAL_TO_MAIN_THREAD */
-
 #if defined (MSDOS) || defined (WINDOWSNT)
   /* We do all file input/output as binary files.  When we need to translate
      newlines, we do that manually.  */
@@ -1111,6 +1106,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
     }
 
   init_signals ();
+  emacs_sigaction_init (&fatal_error_action, deliver_fatal_signal);
 
   /* Don't catch SIGHUP if dumping.  */
   if (1
@@ -1119,13 +1115,17 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
 #endif
       )
     {
-      sigblock (sigmask (SIGHUP));
       /* In --batch mode, don't catch SIGHUP if already ignored.
         That makes nohup work.  */
-      if (! noninteractive
-         || signal (SIGHUP, SIG_IGN) != SIG_IGN)
-       signal (SIGHUP, fatal_error_signal);
-      sigunblock (sigmask (SIGHUP));
+      bool catch_SIGHUP = !noninteractive;
+      if (!catch_SIGHUP)
+       {
+         struct sigaction old_action;
+         sigaction (SIGHUP, 0, &old_action);
+         catch_SIGHUP = old_action.sa_handler != SIG_IGN;
+       }
+      if (catch_SIGHUP)
+       sigaction (SIGHUP, &fatal_error_action, 0);
     }
 
   if (
@@ -1139,9 +1139,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
       /* Don't catch these signals in batch mode if dumping.
         On some machines, this sets static data that would make
         signal fail to work right when the dumped Emacs is run.  */
-      signal (SIGQUIT, fatal_error_signal);
-      signal (SIGILL, fatal_error_signal);
-      signal (SIGTRAP, fatal_error_signal);
+      sigaction (SIGQUIT, &fatal_error_action, 0);
+      sigaction (SIGILL, &fatal_error_action, 0);
+      sigaction (SIGTRAP, &fatal_error_action, 0);
 #ifdef SIGUSR1
       add_user_signal (SIGUSR1, "sigusr1");
 #endif
@@ -1149,68 +1149,73 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
       add_user_signal (SIGUSR2, "sigusr2");
 #endif
 #ifdef SIGABRT
-      signal (SIGABRT, fatal_error_signal);
+      sigaction (SIGABRT, &fatal_error_action, 0);
 #endif
 #ifdef SIGHWE
-      signal (SIGHWE, fatal_error_signal);
+      sigaction (SIGHWE, &fatal_error_action, 0);
 #endif
 #ifdef SIGPRE
-      signal (SIGPRE, fatal_error_signal);
+      sigaction (SIGPRE, &fatal_error_action, 0);
 #endif
 #ifdef SIGORE
-      signal (SIGORE, fatal_error_signal);
+      sigaction (SIGORE, &fatal_error_action, 0);
 #endif
 #ifdef SIGUME
-      signal (SIGUME, fatal_error_signal);
+      sigaction (SIGUME, &fatal_error_action, 0);
 #endif
 #ifdef SIGDLK
-      signal (SIGDLK, fatal_error_signal);
+      sigaction (SIGDLK, &fatal_error_action, 0);
 #endif
 #ifdef SIGCPULIM
-      signal (SIGCPULIM, fatal_error_signal);
+      sigaction (SIGCPULIM, &fatal_error_action, 0);
 #endif
 #ifdef SIGIOT
       /* This is missing on some systems - OS/2, for example.  */
-      signal (SIGIOT, fatal_error_signal);
+      sigaction (SIGIOT, &fatal_error_action, 0);
 #endif
 #ifdef SIGEMT
-      signal (SIGEMT, fatal_error_signal);
+      sigaction (SIGEMT, &fatal_error_action, 0);
 #endif
-      signal (SIGFPE, fatal_error_signal);
+      sigaction (SIGFPE, &fatal_error_action, 0);
 #ifdef SIGBUS
-      signal (SIGBUS, fatal_error_signal);
+      sigaction (SIGBUS, &fatal_error_action, 0);
 #endif
-      signal (SIGSEGV, fatal_error_signal);
+      sigaction (SIGSEGV, &fatal_error_action, 0);
 #ifdef SIGSYS
-      signal (SIGSYS, fatal_error_signal);
+      sigaction (SIGSYS, &fatal_error_action, 0);
 #endif
       /*  May need special treatment on MS-Windows. See
           http://lists.gnu.org/archive/html/emacs-devel/2010-09/msg01062.html
           Please update the doc of kill-emacs, kill-emacs-hook, and
           NEWS if you change this.
       */
-      if (noninteractive) signal (SIGINT, fatal_error_signal);
-      signal (SIGTERM, fatal_error_signal);
+      if (noninteractive)
+       sigaction (SIGINT, &fatal_error_action, 0);
+      sigaction (SIGTERM, &fatal_error_action, 0);
 #ifdef SIGXCPU
-      signal (SIGXCPU, fatal_error_signal);
+      sigaction (SIGXCPU, &fatal_error_action, 0);
 #endif
 #ifdef SIGXFSZ
-      signal (SIGXFSZ, fatal_error_signal);
+      sigaction (SIGXFSZ, &fatal_error_action, 0);
 #endif /* SIGXFSZ */
 
 #ifdef SIGDANGER
       /* This just means available memory is getting low.  */
-      signal (SIGDANGER, memory_warning_signal);
+      {
+       struct sigaction action;
+       emacs_sigaction_init (&action, deliver_danger_signal);
+       sigaction (SIGDANGER, &action, 0);
+      }
 #endif
 
 #ifdef AIX
 /* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU.  */
-      signal (SIGXCPU, fatal_error_signal);
-      signal (SIGIOINT, fatal_error_signal);
-      signal (SIGGRANT, fatal_error_signal);
-      signal (SIGRETRACT, fatal_error_signal);
-      signal (SIGSOUND, fatal_error_signal);
-      signal (SIGMSG, fatal_error_signal);
+      sigaction (SIGXCPU, &fatal_error_action, 0);
+      sigaction (SIGIOINT, &fatal_error_action, 0);
+      sigaction (SIGGRANT, &fatal_error_action, 0);
+      sigaction (SIGRETRACT, &fatal_error_action, 0);
+      sigaction (SIGSOUND, &fatal_error_action, 0);
+      sigaction (SIGMSG, &fatal_error_action, 0);
 #endif /* AIX */
     }
 
@@ -1577,7 +1582,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
   init_fringe ();
 #endif /* HAVE_WINDOW_SYSTEM */
   init_macros ();
-  init_floatfns ();
   init_window ();
   init_font ();
 
@@ -1892,7 +1896,7 @@ sort_args (int argc, char **argv)
        }
 
       if (best < 0)
-       abort ();
+       emacs_abort ();
 
       /* Copy the highest priority remaining option, with its args, to NEW.
          Unless it is a duplicate of the previous one.  */
@@ -1955,7 +1959,7 @@ all of which are called before Emacs is actually killed.  */)
   x_clipboard_manager_save_all ();
 #endif
 
-  shut_down_emacs (0, 0, STRINGP (arg) ? arg : Qnil);
+  shut_down_emacs (0, STRINGP (arg) ? arg : Qnil);
 
 #ifdef HAVE_NS
   ns_release_autorelease_pool (ns_pool);
@@ -1991,7 +1995,7 @@ all of which are called before Emacs is actually killed.  */)
    and Fkill_emacs.  */
 
 void
-shut_down_emacs (int sig, int no_x, Lisp_Object stuff)
+shut_down_emacs (int sig, Lisp_Object stuff)
 {
   /* Prevent running of hooks from now on.  */
   Vrun_hooks = Qnil;
@@ -2008,7 +2012,7 @@ shut_down_emacs (int sig, int no_x, Lisp_Object stuff)
       {
        reset_all_sys_modes ();
        if (sig && sig != SIGTERM)
-         fprintf (stderr, "Fatal error (%d)", sig);
+         fprintf (stderr, "Fatal error %d: %s", sig, strsignal (sig));
       }
   }
 #else
@@ -2026,23 +2030,10 @@ shut_down_emacs (int sig, int no_x, Lisp_Object stuff)
   unlock_all_files ();
 #endif
 
-#if 0 /* This triggers a bug in XCloseDisplay and is not needed.  */
-#ifdef HAVE_X_WINDOWS
-  /* It's not safe to call intern here.  Maybe we are crashing.  */
-  if (!noninteractive && SYMBOLP (Vinitial_window_system)
-      && SCHARS (SYMBOL_NAME (Vinitial_window_system)) == 1
-      && SREF (SYMBOL_NAME (Vinitial_window_system), 0) == 'x'
-      && ! no_x)
-    Fx_close_current_connection ();
-#endif /* HAVE_X_WINDOWS */
-#endif
-
-#ifdef SIGIO
   /* There is a tendency for a SIGIO signal to arrive within exit,
      and cause a SIGHUP because the input descriptor is already closed.  */
   unrequest_sigio ();
-  signal (SIGIO, SIG_IGN);
-#endif
+  ignore_sigio ();
 
 #ifdef WINDOWSNT
   term_ntproc ();
@@ -2148,12 +2139,6 @@ You must run Emacs in batch mode in order to dump it.  */)
     memory_warnings (my_edata, malloc_warning);
   }
 #endif /* not WINDOWSNT */
-#if defined (HAVE_PTHREAD) && !defined SYNC_INPUT
-  /* Pthread may call malloc before main, and then we will get an endless
-     loop, because pthread_self (see alloc.c) calls malloc the first time
-     it is called on some systems.  */
-  reset_malloc_hooks ();
-#endif
 #endif /* not SYSTEM_MALLOC */
 #ifdef DOUG_LEA_MALLOC
   malloc_state_ptr = malloc_get_state ();
@@ -2228,7 +2213,7 @@ decode_env_path (const char *evarname, const char *defalt)
   const char *path, *p;
   Lisp_Object lpath, element, tem;
 #ifdef WINDOWSNT
-  int defaulted = 0;
+  bool defaulted = 0;
   const char *emacs_dir = egetenv ("emacs_dir");
   static const char *emacs_dir_env = "%emacs_dir%/";
   const size_t emacs_dir_len = strlen (emacs_dir_env);
@@ -2324,7 +2309,7 @@ from the parent process and its tty file descriptors.  */)
   (void)
 {
   int nfd;
-  int err = 0;
+  bool err = 0;
 
   if (!IS_DAEMON)
     error ("This function can only be called if emacs is run as a daemon");