Include <config.h> instead of "config.h".
[bpt/emacs.git] / src / emacs.c
index b33bb7f..22d0929 100644 (file)
@@ -1,5 +1,5 @@
 /* Fully extensible Emacs, running on Unix, intended for GNU.
-   Copyright (C) 1985, 1986, 1987, 1992, 1993 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1993 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -21,7 +21,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <signal.h>
 #include <errno.h>
 
-#include "config.h"
+#include <config.h>
 #include <stdio.h>
 
 #include <sys/types.h>
@@ -35,10 +35,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <sys/ioctl.h>
 #endif
 
-#ifdef HAVE_TERMIOS
-#include <termios.h>
-#endif
-
 #ifdef APOLLO
 #ifndef APOLLO_SR10
 #include <default_acl.h>
@@ -51,16 +47,22 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "systty.h"
 #include "syssignal.h"
+#include "process.h"
 
 #ifndef O_RDWR
 #define O_RDWR 2
 #endif
 
-#define PRIO_PROCESS 0
-
 /* Command line args from shell, as list of strings */
 Lisp_Object Vcommand_line_args;
 
+/* The name under which Emacs was invoked, with any leading directory
+   names discarded.  */
+Lisp_Object Vinvocation_name;
+
+/* The directory name from which Emacs was invoked.  */
+Lisp_Object Vinvocation_directory;
+
 /* Hook run by `kill-emacs' before it does really anything.  */
 Lisp_Object Vkill_emacs_hook;
 
@@ -81,6 +83,11 @@ int inhibit_window_system;
    priority; Those functions have their own extern declaration.  */
 int emacs_priority;
 
+#ifdef BSD
+/* See sysdep.c.  */
+extern int inherited_pgroup;
+#endif
+
 #ifdef HAVE_X_WINDOWS
 /* If non-zero, -d was specified, meaning we're using some window system. */
 int display_arg;
@@ -130,7 +137,7 @@ fatal_error_signal (sig)
     {
       fatal_error_in_progress = 1;
 
-      shut_down_emacs (sig);
+      shut_down_emacs (sig, 0, Qnil);
     }
 
 #ifdef VMS
@@ -140,7 +147,7 @@ fatal_error_signal (sig)
      Remember that since we're in a signal handler, the signal we're
      going to send is probably blocked, so we have to unblock it if we
      want to really receive it.  */
-  sigblock(SIGEMPTYMASK);
+  sigunblock (sigmask (fatal_error_code));
   kill (getpid (), fatal_error_code);
 #endif /* not VMS */
 }
@@ -155,6 +162,19 @@ init_cmdargs (argc, argv, skip_args)
 {
   register int i;
 
+  Vinvocation_name = Ffile_name_nondirectory (build_string (argv[0]));
+  Vinvocation_directory = Ffile_name_directory (build_string (argv[0]));
+  /* If we got no directory in argv[0], search PATH to find where
+     Emacs actually came from.  */
+  if (NILP (Vinvocation_directory))
+    {
+      Lisp_Object found;
+      int yes = openp (Vexec_path, Vinvocation_name,
+                      EXEC_SUFFIXES, &found, 1);
+      if (yes == 1)
+       Vinvocation_directory = Ffile_name_directory (found);
+    }
+
   Vcommand_line_args = Qnil;
 
   for (i = argc - 1; i >= 0; i--)
@@ -164,6 +184,23 @@ init_cmdargs (argc, argv, skip_args)
          = Fcons (build_string (argv[i]), Vcommand_line_args);
     }
 }
+
+DEFUN ("invocation-name", Finvocation_name, Sinvocation_name, 0, 0, 0,
+  "Return the program name that was used to run Emacs.\n\
+Any directory names are omitted.")
+  ()
+{
+  return Fcopy_sequence (Vinvocation_name);
+}
+
+DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory,
+  0, 0, 0,
+  "Return the directory name in which the Emacs executable was located")
+  ()
+{
+  return Fcopy_sequence (Vinvocation_directory);
+}
+
 \f
 #ifdef VMS
 #ifdef LINK_CRTL_SHARE
@@ -173,6 +210,7 @@ extern noshare char **environ;
 #endif /* LINK_CRTL_SHARE */
 #endif /* VMS */
 
+#ifndef ORDINARY_LINK
 /* We don't include crtbegin.o and crtend.o in the link,
    so these functions and variables might be missed.
    Provide dummy definitions to avoid error.
@@ -184,11 +222,15 @@ __do_global_ctors_aux ()
 {}
 __do_global_dtors ()
 {}
+/* Linux has a bug in its library; avoid an error.  */
+#ifndef LINUX
 char * __CTOR_LIST__[2] = { (char *) (-1), 0 };
+#endif
 char * __DTOR_LIST__[2] = { (char *) (-1), 0 };
 __main ()
 {}
 #endif /* __GNUC__ */
+#endif /* ORDINARY_LINK */
 
 /* ARGSUSED */
 main (argc, argv, envp)
@@ -220,7 +262,7 @@ main (argc, argv, envp)
 #endif
 
 #ifdef NeXT
-  static int malloc_cookie;
+  extern int malloc_cookie;
 
   /* This helps out unexnext.c.  */
   if (initialized)
@@ -237,7 +279,7 @@ main (argc, argv, envp)
     int i;
 
     for (i = 1; (i < argc && ! display_arg); i++)
-      if (!strcmp (argv[i], "-d"))
+      if (!strcmp (argv[i], "-d") || !strcmp (argv[i], "-display"))
        display_arg = 1;
   }
 #endif
@@ -279,10 +321,15 @@ main (argc, argv, envp)
 #endif
 
   clearerr (stdin);
+
 #ifdef BSD
-  setpgrp (0, getpid ());
+  {
+    inherited_pgroup = getpgrp (0);
+    setpgrp (0, getpid ());
+  }
 #endif
 
+
 #ifdef APOLLO
 #ifndef APOLLO_SR10
   /* If USE_DOMAIN_ACLS environment variable exists,
@@ -294,7 +341,14 @@ main (argc, argv, envp)
 
 #ifndef SYSTEM_MALLOC
   if (! initialized)
-    memory_warnings (0, malloc_warning);
+    {
+      /* Arrange to get warning messages as memory fills up.  */
+      memory_warnings (0, malloc_warning);
+
+      /* Arrange to disable interrupt input while malloc and friends are
+        running.  */
+      uninterrupt_malloc ();
+    }
 #endif /* not SYSTEM_MALLOC */
 
 #ifdef PRIO_PROCESS
@@ -303,11 +357,6 @@ main (argc, argv, envp)
   setuid (getuid ());
 #endif /* PRIO_PROCESS */
 
-#ifdef BSD
-  /* interrupt_input has trouble if we aren't in a separate process group.  */
-  setpgrp (getpid (), getpid ());
-#endif
-
   inhibit_window_system = 0;
 
   /* Handle the -t switch, which specifies filename to use as terminal */
@@ -375,14 +424,21 @@ main (argc, argv, envp)
       signal (SIGQUIT, fatal_error_signal);
       signal (SIGILL, fatal_error_signal);
       signal (SIGTRAP, fatal_error_signal);
+#ifdef SIGIOT
+      /* This is missing on some systems - OS/2, for example.  */
       signal (SIGIOT, fatal_error_signal);
+#endif
 #ifdef SIGEMT
       signal (SIGEMT, fatal_error_signal);
 #endif
       signal (SIGFPE, fatal_error_signal);
+#ifdef SIGBUS
       signal (SIGBUS, fatal_error_signal);
+#endif
       signal (SIGSEGV, fatal_error_signal);
+#ifdef SIGSYS
       signal (SIGSYS, fatal_error_signal);
+#endif
       signal (SIGTERM, fatal_error_signal);
 #ifdef SIGXCPU
       signal (SIGXCPU, fatal_error_signal);
@@ -402,7 +458,9 @@ main (argc, argv, envp)
       signal (SIGAIO, fatal_error_signal);
       signal (SIGPTY, fatal_error_signal);
 #endif
+#ifndef _I386
       signal (SIGIOINT, fatal_error_signal);
+#endif
       signal (SIGGRANT, fatal_error_signal);
       signal (SIGRETRACT, fatal_error_signal);
       signal (SIGSOUND, fatal_error_signal);
@@ -437,10 +495,12 @@ main (argc, argv, envp)
      until calling init_callproc.  */
   set_process_environment ();
 
+  init_buffer ();      /* Init default directory of main buffer */
+
+  init_callproc ();    /* Must precede init_cmdargs and init_sys_modes.  */
+  init_cmdargs (argc, argv, skip_args);        /* Must precede init_lread.  */
   init_lread ();
 
-  init_cmdargs (argc, argv, skip_args);        /* Create list Vcommand_line_args */
-  init_buffer ();      /* Init default directory of main buffer */
   if (!noninteractive)
     {
 #ifdef VMS
@@ -449,7 +509,6 @@ main (argc, argv, envp)
       init_display (); /* Determine terminal type.  init_sys_modes uses results */
     }
   init_keyboard ();    /* This too must precede init_sys_modes */
-  init_callproc ();    /* And this too. */
 #ifdef VMS
   init_vmsproc ();     /* And this too. */
 #endif /* VMS */
@@ -481,9 +540,7 @@ main (argc, argv, envp)
       syms_of_print ();
       syms_of_eval ();
       syms_of_fns ();
-#ifdef LISP_FLOAT_TYPE
       syms_of_floatfns ();
-#endif
 
       syms_of_abbrev ();
       syms_of_buffer ();
@@ -527,6 +584,7 @@ main (argc, argv, envp)
 #ifdef HAVE_X_WINDOWS
       syms_of_xterm ();
       syms_of_xfns ();
+      syms_of_xfaces ();
 #ifdef HAVE_X11
       syms_of_xselect ();
 #endif
@@ -570,14 +628,14 @@ main (argc, argv, envp)
 
   initialized = 1;
 
-#ifdef sun
-  /* sun's localtime() has a bug.  it caches the value of the time
+#if defined (sun) || defined (LOCALTIME_CACHE)
+  /* sun's localtime has a bug.  it caches the value of the time
      zone rather than looking it up every time.  Since localtime() is
      called to bolt the undumping time into the undumped emacs, this
-     results in localtime() ignoring the TZ environment variable.
-     This flushes the new TZ value into localtime(). */
-  tzset();
-#endif /* sun */
+     results in localtime ignoring the TZ environment variable.
+     This flushes the new TZ value into localtime. */
+  tzset ();
+#endif /* defined (sun) || defined (LOCALTIME_CACHE) */
 
   /* Enter editor command loop.  This never returns.  */
   Frecursive_edit ();
@@ -606,11 +664,6 @@ all of which are called before Emacs is actually killed.")
   if (!NILP (Vrun_hooks) && !noninteractive)
     call1 (Vrun_hooks, intern ("kill-emacs-hook"));
 
-#ifdef HAVE_X_WINDOWS
-  if (!noninteractive && EQ (Vwindow_system, intern ("x")))
-    Fx_close_current_connection ();
-#endif /* HAVE_X_WINDOWS */
-
   UNGCPRO;
 
 /* Is it really necessary to do this deassign
@@ -618,9 +671,8 @@ all of which are called before Emacs is actually killed.")
 /* #ifdef VMS
   stop_vms_input ();
  #endif  */
-  stuff_buffered_input (arg);
 
-  shut_down_emacs (0);
+  shut_down_emacs (0, 0, STRINGP (arg) ? arg : Qnil);
 
   exit ((XTYPE (arg) == Lisp_Int) ? XINT (arg)
 #ifdef VMS
@@ -643,16 +695,23 @@ all of which are called before Emacs is actually killed.")
 
    This is called by fatal signal handlers, X protocol error handlers,
    and Fkill_emacs.  */
+
 void
-shut_down_emacs (sig)
-     int sig;
+shut_down_emacs (sig, no_x, stuff)
+     int sig, no_x;
+     Lisp_Object stuff;
 {
   /* If we are controlling the terminal, reset terminal modes */
 #ifdef EMACS_HAVE_TTY_PGRP
   {
+#ifdef USG
+    int pgrp = getpgrp ();
+#else
+    int pgrp = getpgrp (0);
+#endif
     int tpgrp;
     if (EMACS_GET_TTY_PGRP (0, &tpgrp) != -1
-       && tpgrp == getpgrp (0))
+       && tpgrp == pgrp)
       {
        fflush (stdout);
        reset_sys_modes ();
@@ -665,6 +724,8 @@ shut_down_emacs (sig)
   reset_sys_modes ();
 #endif
 
+  stuff_buffered_input (stuff);
+
   kill_buffer_processes (Qnil);
   Fdo_auto_save (Qt, Qnil);
 
@@ -676,6 +737,11 @@ shut_down_emacs (sig)
   kill_vms_processes ();
 #endif
 
+#ifdef HAVE_X_WINDOWS
+  if (!noninteractive && EQ (Vwindow_system, intern ("x")) && ! no_x)
+    Fx_close_current_connection ();
+#endif /* HAVE_X_WINDOWS */
+
 #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.  */
@@ -772,9 +838,7 @@ and announce itself normally when it is run.")
 
 #endif /* not CANNOT_DUMP */
 \f
-#ifdef VMS
-#define SEPCHAR ','
-#else
+#ifndef SEPCHAR
 #define SEPCHAR ':'
 #endif
 
@@ -813,14 +877,19 @@ decode_env_path (evarname, defalt)
 
 syms_of_emacs ()
 {
+#ifndef CANNOT_DUMP
 #ifdef HAVE_SHM
   defsubr (&Sdump_emacs_data);
 #else
   defsubr (&Sdump_emacs);
+#endif
 #endif
 
   defsubr (&Skill_emacs);
 
+  defsubr (&Sinvocation_name);
+  defsubr (&Sinvocation_directory);
+
   DEFVAR_LISP ("command-line-args", &Vcommand_line_args,
     "Args passed by shell to Emacs, as a list of strings.");
 
@@ -835,7 +904,7 @@ syms_of_emacs ()
     "Hook to be run whenever kill-emacs is called.\n\
 Since kill-emacs may be invoked when the terminal is disconnected (or\n\
 in other similar situations), functions placed on this hook should not\n\
-not expect to be able to interact with the user.");
+expect to be able to interact with the user.");
   Vkill_emacs_hook = Qnil;
 
   DEFVAR_INT ("emacs-priority", &emacs_priority,
@@ -844,4 +913,9 @@ This value is effective only if set before Emacs is dumped,\n\
 and only if the Emacs executable is installed with setuid to permit\n\
 it to change priority.  (Emacs sets its uid back to the real uid.)");
   emacs_priority = 0;
+
+  staticpro (&Vinvocation_name);
+  Vinvocation_name = Qnil;
+  staticpro (&Vinvocation_directory);
+  Vinvocation_directory = Qnil;
 }