159813Shibler /* Fully extensible Emacs, running on Unix, intended for GNU.
259813Shibler    Copyright (C) 1985, 1986, 1987, 1990 Free Software Foundation, Inc.
359813Shibler 
459813Shibler This file is part of GNU Emacs.
559813Shibler 
659813Shibler GNU Emacs is free software; you can redistribute it and/or modify
759813Shibler it under the terms of the GNU General Public License as published by
859813Shibler the Free Software Foundation; either version 1, or (at your option)
959813Shibler any later version.
1059813Shibler 
1159813Shibler GNU Emacs is distributed in the hope that it will be useful,
1259813Shibler but WITHOUT ANY WARRANTY; without even the implied warranty of
1359813Shibler MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1459813Shibler GNU General Public License for more details.
1559813Shibler 
1659813Shibler You should have received a copy of the GNU General Public License
1759813Shibler along with GNU Emacs; see the file COPYING.  If not, write to
1859813Shibler the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
1959813Shibler 
2059813Shibler 
2159813Shibler #include <signal.h>
2259813Shibler #include <errno.h>
2359813Shibler 
2459813Shibler #include "config.h"
2559813Shibler #include <stdio.h>
2659813Shibler #undef NULL
2759813Shibler #include "lisp.h"
2859813Shibler #include "commands.h"
2959813Shibler 
3059813Shibler #include <sys/types.h>
3159813Shibler #include <sys/file.h>
3259813Shibler 
3359813Shibler #ifdef VMS
3459813Shibler #include <ssdef.h>
3559813Shibler #endif
3659813Shibler 
3759813Shibler #ifdef USG5
3859813Shibler #include <fcntl.h>
3959813Shibler #endif
4059813Shibler 
4159813Shibler #ifdef BSD
4259813Shibler #include <sys/ioctl.h>
4359813Shibler #endif
4459813Shibler 
4559813Shibler #ifdef APOLLO
4659813Shibler #ifndef APOLLO_SR10
4759813Shibler #include <default_acl.h>
4859813Shibler #endif
4959813Shibler #endif
5059813Shibler 
5159813Shibler #ifndef O_RDWR
5259813Shibler #define O_RDWR 2
5359813Shibler #endif
5459813Shibler 
5559813Shibler #define PRIO_PROCESS 0
5659813Shibler 
5759813Shibler /* Command line args from shell, as list of strings */
5859813Shibler Lisp_Object Vcommand_line_args;
5959813Shibler 
6059813Shibler /* Hook run by `kill-emacs' before it does really anything.  */
6159813Shibler Lisp_Object Vkill_emacs_hook;
6259813Shibler 
6359813Shibler /* Set nonzero after Emacs has started up the first time.
6459813Shibler   Prevents reinitialization of the Lisp world and keymaps
6559813Shibler   on subsequent starts.  */
6659813Shibler int initialized;
6759813Shibler 
6859813Shibler /* Variable whose value is symbol giving operating system type */
6959813Shibler Lisp_Object Vsystem_type;
7059813Shibler 
7159813Shibler /* If non-zero, emacs should not attempt to use an window-specific code,
7259813Shibler    but instead should use the virtual terminal under which it was started */
7359813Shibler int inhibit_window_system;
7459813Shibler 
7559813Shibler #ifdef HAVE_X_WINDOWS
7659813Shibler /* If -d option is used, this variable points to the name of
7759813Shibler    the display to use.  */
7859813Shibler char *alternate_display;
7959813Shibler char **xargv;
8059813Shibler int xargc;
8159813Shibler #endif /* HAVE_X_WINDOWS */
8259813Shibler 
8359813Shibler #ifdef USG_SHARED_LIBRARIES
8459813Shibler /* If nonzero, this is the place to put the end of the writable segment
8559813Shibler    at startup.  */
8659813Shibler 
8759813Shibler unsigned int bss_end = 0;
8859813Shibler #endif
8959813Shibler 
9059813Shibler /* Nonzero means running Emacs without interactive terminal.  */
9159813Shibler 
9259813Shibler int noninteractive;
9359813Shibler 
9459813Shibler /* Value of Lisp variable `noninteractive'.
9559813Shibler    Normally same as C variable `noninteractive'
9659813Shibler    but nothing terrible happens if user sets this one.  */
9759813Shibler 
9859813Shibler int noninteractive1;
9959813Shibler 
10059813Shibler /* Signal code for the fatal signal that was received */
10159813Shibler int fatal_error_code;
10259813Shibler 
10359813Shibler /* Nonzero if handling a fatal error already */
10459813Shibler int fatal_error_in_progress;
10559813Shibler 
10659813Shibler /* Handle bus errors, illegal instruction, etc. */
fatal_error_signal(sig)10759813Shibler fatal_error_signal (sig)
10859813Shibler      int sig;
10959813Shibler {
11059813Shibler #ifdef BSD
11159813Shibler   int tpgrp;
11259813Shibler #endif /* BSD */
11359813Shibler 
11459813Shibler   fatal_error_code = sig;
11559813Shibler   signal (sig, SIG_DFL);
11659813Shibler 
11759813Shibler   /* If fatal error occurs in code below, avoid infinite recursion.  */
11859813Shibler   if (fatal_error_in_progress)
11959813Shibler     kill (getpid (), fatal_error_code);
12059813Shibler 
12159813Shibler   fatal_error_in_progress = 1;
12259813Shibler 
12359813Shibler   /* If we are controlling the terminal, reset terminal modes */
12459813Shibler #ifdef BSD
12559813Shibler   if (ioctl(0, TIOCGPGRP, &tpgrp) == 0
12659813Shibler       && tpgrp == getpgrp (0))
12759813Shibler #endif /* BSD */
12859813Shibler     {
12959813Shibler       reset_sys_modes ();
13059813Shibler       if (sig != SIGTERM)
13159813Shibler 	fprintf (stderr, "Fatal error (%d).", sig);
13259813Shibler     }
13359813Shibler 
13459813Shibler   /* Clean up */
13559813Shibler #ifdef subprocesses
13659813Shibler   kill_buffer_processes (Qnil);
13759813Shibler #endif
13859813Shibler   Fdo_auto_save (Qt);
13959813Shibler 
14059813Shibler #ifdef CLASH_DETECTION
14159813Shibler   unlock_all_files ();
14259813Shibler #endif /* CLASH_DETECTION */
14359813Shibler 
14459813Shibler #ifdef VMS
14559813Shibler   kill_vms_processes ();
14659813Shibler   LIB$STOP (SS$_ABORT);
14759813Shibler #else
14859813Shibler   /* Signal the same code; this time it will really be fatal.  */
14959813Shibler   kill (getpid (), fatal_error_code);
15059813Shibler #endif /* not VMS */
15159813Shibler }
15259813Shibler 
15359813Shibler /* Code for dealing with Lisp access to the Unix command line */
15459813Shibler 
15559813Shibler static
init_cmdargs(argc,argv,skip_args)15659813Shibler init_cmdargs (argc, argv, skip_args)
15759813Shibler      int argc;
15859813Shibler      char **argv;
15959813Shibler      int skip_args;
16059813Shibler {
16159813Shibler   register int i;
16259813Shibler 
16359813Shibler   Vcommand_line_args = Qnil;
16459813Shibler 
16559813Shibler   for (i = argc - 1; i >= 0; i--)
16659813Shibler     {
16759813Shibler       if (i == 0 || i > skip_args)
16859813Shibler 	Vcommand_line_args
16959813Shibler 	  = Fcons (build_string (argv[i]), Vcommand_line_args);
17059813Shibler     }
17159813Shibler }
17259813Shibler 
17359813Shibler #ifdef VMS
17459813Shibler #ifdef LINK_CRTL_SHARE
17559813Shibler #ifdef SHAREABLE_LIB_BUG
17659813Shibler extern noshare char **environ;
17759813Shibler #endif /* SHAREABLE_LIB_BUG */
17859813Shibler #endif /* LINK_CRTL_SHARE */
17959813Shibler #endif /* VMS */
18059813Shibler 
181*60297Shibler /* We don't include crtbegin.o and crtend.o in the link,
182*60297Shibler    so these functions and variables might be missed.
183*60297Shibler    Provide dummy definitions to avoid error.
184*60297Shibler    (We don't have any real constructors or destructors.)  */
185*60297Shibler #ifdef __GNUC__
186*60297Shibler #ifndef ORDINARY_LINK
__do_clobal_ctors()187*60297Shibler __do_clobal_ctors ()
188*60297Shibler {}
__do_clobal_ctors_aux()189*60297Shibler __do_clobal_ctors_aux ()
190*60297Shibler {}
__do_global_dtors()191*60297Shibler __do_global_dtors ()
192*60297Shibler {}
193*60297Shibler char * __CTOR_LIST__[2] = { (char *) (-1), 0 };
194*60297Shibler char * __DTOR_LIST__[2] = { (char *) (-1), 0 };
__main()195*60297Shibler __main ()
196*60297Shibler {}
197*60297Shibler #endif /* not ORDINARY_LINK */
198*60297Shibler #endif /* __GNUC__ */
199*60297Shibler 
20059813Shibler /* ARGSUSED */
main(argc,argv,envp)20159813Shibler main (argc, argv, envp)
20259813Shibler      int argc;
20359813Shibler      char **argv;
20459813Shibler      char **envp;
20559813Shibler {
20659813Shibler   int skip_args = 0;
20759813Shibler   extern int errno;
20859813Shibler   extern void malloc_warning ();
20959813Shibler 
21059813Shibler /* Map in shared memory, if we are using that.  */
21159813Shibler #ifdef HAVE_SHM
21259813Shibler   if (argc > 1 && !strcmp (argv[1], "-nl"))
21359813Shibler     {
21459813Shibler       map_in_data (0);
21559813Shibler       /* The shared momory was just restored, which clobbered this.  */
21659813Shibler       skip_args = 1;
21759813Shibler     }
21859813Shibler   else
21959813Shibler     {
22059813Shibler       map_in_data (1);
22159813Shibler       /* The shared momory was just restored, which clobbered this.  */
22259813Shibler       skip_args = 0;
22359813Shibler     }
22459813Shibler #endif
22559813Shibler 
22659813Shibler #ifdef VMS
22759813Shibler   /* If -map specified, map the data file in */
22859813Shibler   if (argc > 2 && ! strcmp (argv[1], "-map"))
22959813Shibler     {
23059813Shibler       skip_args = 2;
23159813Shibler       mapin_data (argv[2]);
23259813Shibler     }
23359813Shibler 
23459813Shibler #ifdef LINK_CRTL_SHARE
23559813Shibler #ifdef SHAREABLE_LIB_BUG
23659813Shibler   /* Bletcherous shared libraries! */
23759813Shibler   if (!stdin)
23859813Shibler     stdin = fdopen (0, "r");
23959813Shibler   if (!stdout)
24059813Shibler     stdout = fdopen (1, "w");
24159813Shibler   if (!stderr)
24259813Shibler     stderr = fdopen (2, "w");
24359813Shibler   if (!environ)
24459813Shibler     environ = envp;
24559813Shibler #endif /* SHAREABLE_LIB_BUG */
24659813Shibler #endif /* LINK_CRTL_SHARE */
24759813Shibler #endif /* VMS */
24859813Shibler 
24959813Shibler #ifdef USG_SHARED_LIBRARIES
25059813Shibler   if (bss_end)
25159813Shibler     brk (bss_end);
25259813Shibler #endif
25359813Shibler 
25459813Shibler   clearerr (stdin);
25559813Shibler 
25659813Shibler #ifdef APOLLO
25759813Shibler #ifndef APOLLO_SR10
25859813Shibler   /* If USE_DOMAIN_ACLS environment variable exists,
25959813Shibler      use ACLs rather than UNIX modes. */
26059813Shibler   if (egetenv ("USE_DOMAIN_ACLS"))
26159813Shibler     default_acl (USE_DEFACL);
26259813Shibler #endif
26359813Shibler #endif /* APOLLO */
26459813Shibler 
26559813Shibler #ifndef SYSTEM_MALLOC
26659813Shibler   /* Arrange for warnings when nearly out of space.  */
26759813Shibler   malloc_init (0, malloc_warning);
26859813Shibler #endif
26959813Shibler 
27059813Shibler #ifdef HIGHPRI
27159813Shibler   setpriority (PRIO_PROCESS, getpid (), HIGHPRI);
27259813Shibler   setuid (getuid ());
27359813Shibler #endif HIGHPRI
27459813Shibler 
27559813Shibler   inhibit_window_system = 0;
27659813Shibler 
27759813Shibler #ifdef HAVE_X_WINDOWS
27859813Shibler   xargv = argv;
27959813Shibler   xargc = argc;
28059813Shibler #endif
28159813Shibler 
28259813Shibler /* Handle the -t switch, which specifies filename to use as terminal */
28359813Shibler   if (skip_args + 2 < argc && !strcmp (argv[skip_args + 1], "-t"))
28459813Shibler     {
28559813Shibler       skip_args += 2;
28659813Shibler       close (0);
28759813Shibler       close (1);
28859813Shibler       open (argv[skip_args], O_RDWR, 2 );
28959813Shibler       dup (0);
29059813Shibler       fprintf (stderr, "Using %s\n", argv[skip_args]);
29159813Shibler #ifdef HAVE_X_WINDOWS
29259813Shibler       inhibit_window_system = 1;	/* -t => -nw */
29359813Shibler #endif
29459813Shibler     }
29559813Shibler #ifdef HAVE_X_WINDOWS
29659813Shibler /* Handle the -d switch, which means use a different display for X */
29759813Shibler   if (skip_args + 2 < argc && (!strcmp (argv[skip_args + 1], "-d") ||
29859813Shibler 			       !strcmp (argv[skip_args + 1], "-display")))
29959813Shibler     {
30059813Shibler       skip_args += 2;
30159813Shibler       alternate_display = argv[skip_args];
30259813Shibler     }
30359813Shibler   else
30459813Shibler     alternate_display = 0;
30559813Shibler #endif	/* HAVE_X_WINDOWS */
30659813Shibler 
30759813Shibler   if (skip_args + 1 < argc
30859813Shibler       && (!strcmp (argv[skip_args + 1], "-nw")))
30959813Shibler     {
31059813Shibler       skip_args += 1;
31159813Shibler       inhibit_window_system = 1;
31259813Shibler     }
31359813Shibler 
31459813Shibler /* Handle the -batch switch, which means don't do interactive display.  */
31559813Shibler   noninteractive = 0;
31659813Shibler   if (skip_args + 1 < argc && !strcmp (argv[skip_args + 1], "-batch"))
31759813Shibler     {
31859813Shibler       skip_args += 1;
31959813Shibler       noninteractive = 1;
32059813Shibler     }
32159813Shibler 
32259813Shibler   if (
32359813Shibler #ifndef CANNOT_DUMP
32459813Shibler       ! noninteractive || initialized
32559813Shibler #else
32659813Shibler       1
32759813Shibler #endif
32859813Shibler       )
32959813Shibler     {
33059813Shibler       /* Don't catch these signals in batch mode if not initialized.
33159813Shibler 	 On some machines, this sets static data that would make
33259813Shibler 	 signal fail to work right when the dumped Emacs is run.  */
33359813Shibler       signal (SIGHUP, fatal_error_signal);
33459813Shibler       signal (SIGQUIT, fatal_error_signal);
33559813Shibler       signal (SIGILL, fatal_error_signal);
33659813Shibler       signal (SIGTRAP, fatal_error_signal);
33759813Shibler       signal (SIGIOT, fatal_error_signal);
33859813Shibler #ifdef SIGEMT
33959813Shibler       signal (SIGEMT, fatal_error_signal);
34059813Shibler #endif
34159813Shibler       signal (SIGFPE, fatal_error_signal);
34259813Shibler       signal (SIGBUS, fatal_error_signal);
34359813Shibler       signal (SIGSEGV, fatal_error_signal);
34459813Shibler       signal (SIGSYS, fatal_error_signal);
34559813Shibler       signal (SIGTERM, fatal_error_signal);
34659813Shibler #ifdef SIGXCPU
34759813Shibler       signal (SIGXCPU, fatal_error_signal);
34859813Shibler #endif
34959813Shibler #ifdef SIGXFSZ
35059813Shibler       signal (SIGXFSZ, fatal_error_signal);
35159813Shibler #endif SIGXFSZ
35259813Shibler 
35359813Shibler #ifdef AIX
35459813Shibler       signal (SIGDANGER, fatal_error_signal);
35559813Shibler       signal (20, fatal_error_signal);
35659813Shibler       signal (21, fatal_error_signal);
35759813Shibler       signal (22, fatal_error_signal);
35859813Shibler       signal (23, fatal_error_signal);
35959813Shibler       signal (24, fatal_error_signal);
36059813Shibler       signal (SIGAIO, fatal_error_signal);
36159813Shibler       signal (SIGPTY, fatal_error_signal);
36259813Shibler       signal (SIGIOINT, fatal_error_signal);
36359813Shibler       signal (SIGGRANT, fatal_error_signal);
36459813Shibler       signal (SIGRETRACT, fatal_error_signal);
36559813Shibler       signal (SIGSOUND, fatal_error_signal);
36659813Shibler       signal (SIGMSG, fatal_error_signal);
36759813Shibler #endif /* AIX */
36859813Shibler     }
36959813Shibler 
37059813Shibler   noninteractive1 = noninteractive;
37159813Shibler 
37259813Shibler /* Perform basic initializations (not merely interning symbols) */
37359813Shibler 
37459813Shibler   if (!initialized)
37559813Shibler     {
37659813Shibler       init_alloc_once ();
37759813Shibler       init_obarray ();
37859813Shibler       init_eval_once ();
37959813Shibler       init_syntax_once ();	/* Create standard syntax table.  */
38059813Shibler 		      /* Must be done before init_buffer */
38159813Shibler       init_buffer_once ();	/* Create buffer table and some buffers */
38259813Shibler       init_minibuf_once ();	/* Create list of minibuffers */
38359813Shibler 			      /* Must precede init_window_once */
38459813Shibler       init_window_once ();	/* Init the window system */
38559813Shibler     }
38659813Shibler 
38759813Shibler   init_alloc ();
38859813Shibler #ifdef MAINTAIN_ENVIRONMENT
38959813Shibler   init_environ ();
39059813Shibler #endif
39159813Shibler   init_eval ();
39259813Shibler   init_data ();
39359813Shibler   init_read ();
39459813Shibler 
39559813Shibler   init_cmdargs (argc, argv, skip_args);	/* Create list Vcommand_line_args */
39659813Shibler   init_buffer ();	/* Init default directory of main buffer */
39759813Shibler   if (!noninteractive)
39859813Shibler     {
39959813Shibler #ifdef VMS
40059813Shibler       init_vms_input ();/* init_display calls get_screen_size, that needs this */
40159813Shibler #endif /* VMS */
40259813Shibler       init_display ();	/* Determine terminal type.  init_sys_modes uses results */
40359813Shibler     }
40459813Shibler   init_keyboard ();	/* This too must precede init_sys_modes */
40559813Shibler   init_callproc ();	/* And this too. */
40659813Shibler   init_sys_modes ();	/* Init system terminal modes (RAW or CBREAK, etc.) */
40759813Shibler   init_xdisp ();
40859813Shibler   init_macros ();
40959813Shibler   init_editfns ();
41059813Shibler #ifdef VMS
41159813Shibler   init_vmsfns ();
41259813Shibler #endif /* VMS */
41359813Shibler #ifdef subprocesses
41459813Shibler   init_process ();
41559813Shibler #endif /* subprocesses */
41659813Shibler 
41759813Shibler /* Intern the names of all standard functions and variables; define standard keys */
41859813Shibler 
41959813Shibler   if (!initialized)
42059813Shibler     {
42159813Shibler       /* The basic levels of Lisp must come first */
42259813Shibler       /* And data must come first of all
42359813Shibler 	 for the sake of symbols like error-message */
42459813Shibler       syms_of_data ();
42559813Shibler       syms_of_alloc ();
42659813Shibler #ifdef MAINTAIN_ENVIRONMENT
42759813Shibler       syms_of_environ ();
42859813Shibler #endif MAINTAIN_ENVIRONMENT
42959813Shibler       syms_of_read ();
43059813Shibler       syms_of_print ();
43159813Shibler       syms_of_eval ();
43259813Shibler       syms_of_fns ();
43359813Shibler 
43459813Shibler       syms_of_abbrev ();
43559813Shibler       syms_of_buffer ();
43659813Shibler       syms_of_bytecode ();
43759813Shibler       syms_of_callint ();
43859813Shibler       syms_of_casefiddle ();
43959813Shibler       syms_of_callproc ();
44059813Shibler       syms_of_cmds ();
44159813Shibler #ifndef NO_DIR_LIBRARY
44259813Shibler       syms_of_dired ();
44359813Shibler #endif /* not NO_DIR_LIBRARY */
44459813Shibler       syms_of_display ();
44559813Shibler       syms_of_doc ();
44659813Shibler       syms_of_editfns ();
44759813Shibler       syms_of_emacs ();
44859813Shibler       syms_of_fileio ();
44959813Shibler #ifdef CLASH_DETECTION
45059813Shibler       syms_of_filelock ();
45159813Shibler #endif /* CLASH_DETECTION */
45259813Shibler       syms_of_indent ();
45359813Shibler       syms_of_keyboard ();
45459813Shibler       syms_of_keymap ();
45559813Shibler       syms_of_macros ();
45659813Shibler       syms_of_marker ();
45759813Shibler       syms_of_minibuf ();
45859813Shibler       syms_of_mocklisp ();
45959813Shibler #ifdef subprocesses
46059813Shibler       syms_of_process ();
46159813Shibler #endif /* subprocesses */
46259813Shibler       syms_of_search ();
46359813Shibler       syms_of_syntax ();
46459813Shibler       syms_of_undo ();
46559813Shibler       syms_of_window ();
46659813Shibler       syms_of_xdisp ();
46759813Shibler #ifdef HAVE_X_WINDOWS
46859813Shibler       syms_of_xfns ();
46959813Shibler #ifdef HAVE_X_MENU
47059813Shibler       syms_of_xmenu ();
47159813Shibler #endif /* HAVE_X_MENU */
47259813Shibler #endif /* HAVE_X_WINDOWS */
47359813Shibler 
47459813Shibler #ifdef SYMS_SYSTEM
47559813Shibler       SYMS_SYSTEM;
47659813Shibler #endif
47759813Shibler 
47859813Shibler #ifdef SYMS_MACHINE
47959813Shibler       SYMS_MACHINE;
48059813Shibler #endif
48159813Shibler 
48259813Shibler       keys_of_casefiddle ();
48359813Shibler       keys_of_cmds ();
48459813Shibler       keys_of_buffer ();
48559813Shibler       keys_of_keyboard ();
48659813Shibler       keys_of_keymap ();
48759813Shibler       keys_of_macros ();
48859813Shibler       keys_of_minibuf ();
48959813Shibler       keys_of_window ();
49059813Shibler     }
49159813Shibler 
49259813Shibler   if (!initialized)
49359813Shibler     {
49459813Shibler       /* Handle -l loadup-and-dump, args passed by Makefile. */
49559813Shibler       if (argc > 2 + skip_args && !strcmp (argv[1 + skip_args], "-l"))
49659813Shibler 	Vtop_level = Fcons (intern ("load"),
49759813Shibler 			    Fcons (build_string (argv[2 + skip_args]), Qnil));
49859813Shibler #ifdef CANNOT_DUMP
49959813Shibler       /* Unless next switch is -nl, load "loadup.el" first thing.  */
50059813Shibler       if (!(argc > 1 + skip_args && !strcmp (argv[1 + skip_args], "-nl")))
50159813Shibler 	Vtop_level = Fcons (intern ("load"),
50259813Shibler 			    Fcons (build_string ("loadup.el"), Qnil));
50359813Shibler #endif /* CANNOT_DUMP */
50459813Shibler     }
50559813Shibler 
50659813Shibler   initialized = 1;
50759813Shibler 
50859813Shibler   /* Enter editor command loop.  This never returns.  */
50959813Shibler   Frecursive_edit ();
51059813Shibler   /* NOTREACHED */
51159813Shibler }
51259813Shibler 
51359813Shibler DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P",
51459813Shibler   "Exit the Emacs job and kill it.  ARG means no query.\n\
51559813Shibler If emacs is running noninteractively and ARG is an integer,\n\
51659813Shibler return ARG as the exit program code.")
51759813Shibler   (arg)
51859813Shibler      Lisp_Object arg;
51959813Shibler {
52059813Shibler   Lisp_Object answer;
52159813Shibler   int i;
52259813Shibler   struct gcpro gcpro1;
52359813Shibler 
52459813Shibler   GCPRO1 (arg);
52559813Shibler 
52659813Shibler   if (!NULL (Vkill_emacs_hook))
52759813Shibler     call0 (Vkill_emacs_hook);
52859813Shibler 
52959813Shibler   if (feof (stdin))
53059813Shibler     arg = Qt;
53159813Shibler 
53259813Shibler #ifdef subprocesses
53359813Shibler   kill_buffer_processes (Qnil);
53459813Shibler #endif /* subprocesses */
53559813Shibler 
53659813Shibler #ifdef VMS
53759813Shibler   kill_vms_processes ();
53859813Shibler #endif /* VMS */
53959813Shibler 
54059813Shibler   Fdo_auto_save (Qt);
54159813Shibler 
54259813Shibler #ifdef CLASH_DETECTION
54359813Shibler   unlock_all_files ();
54459813Shibler #endif /* CLASH_DETECTION */
54559813Shibler 
54659813Shibler   fflush (stdout);
54759813Shibler   reset_sys_modes ();
54859813Shibler   UNGCPRO;
54959813Shibler 
55059813Shibler /* Is it really necessary to do this deassign
55159813Shibler    when we are going to exit anyway?  */
55259813Shibler /* #ifdef VMS
55359813Shibler   stop_vms_input ();
55459813Shibler  #endif  */
55559813Shibler   stuff_buffered_input (arg);
55659813Shibler #ifdef SIGIO
55759813Shibler   /* There is a tendency for a SIGIO signal to arrive within exit,
55859813Shibler      and cause a SIGHUP because the input descriptor is already closed.  */
55959813Shibler   unrequest_sigio ();
56059813Shibler   signal (SIGIO, SIG_IGN);
56159813Shibler #endif
56259813Shibler   exit ((XTYPE (arg) == Lisp_Int) ? XINT (arg)
56359813Shibler #ifdef VMS
56459813Shibler 	: 1
56559813Shibler #else
56659813Shibler 	: 0
56759813Shibler #endif
56859813Shibler 	);
56959813Shibler   /* NOTREACHED */
57059813Shibler }
57159813Shibler 
57259813Shibler #ifndef CANNOT_DUMP
57359813Shibler /* Nothing like this can be implemented on an Apollo.
57459813Shibler    What a loss!  */
57559813Shibler 
57659813Shibler #ifdef HAVE_SHM
57759813Shibler 
57859813Shibler DEFUN ("dump-emacs-data", Fdump_emacs_data, Sdump_emacs_data, 1, 1, 0,
57959813Shibler   "Dump current state of Emacs into data file FILENAME.\n\
58059813Shibler This function exists on systems that use HAVE_SHM.")
58159813Shibler   (intoname)
58259813Shibler      Lisp_Object intoname;
58359813Shibler {
58459813Shibler   extern int my_edata;
58559813Shibler   Lisp_Object tem;
58659813Shibler   extern void malloc_warning ();
58759813Shibler 
58859813Shibler   CHECK_STRING (intoname, 0);
58959813Shibler   intoname = Fexpand_file_name (intoname, Qnil);
59059813Shibler 
59159813Shibler   tem = Vpurify_flag;
59259813Shibler   Vpurify_flag = Qnil;
59359813Shibler 
59459813Shibler   fflush (stdout);
59559813Shibler   /* Tell malloc where start of impure now is */
59659813Shibler   /* Also arrange for warnings when nearly out of space.  */
59759813Shibler #ifndef SYSTEM_MALLOC
59859813Shibler   malloc_init (&my_edata, malloc_warning);
59959813Shibler #endif
60059813Shibler   map_out_data (XSTRING (intoname)->data);
60159813Shibler 
60259813Shibler   Vpurify_flag = tem;
60359813Shibler 
60459813Shibler   return Qnil;
60559813Shibler }
60659813Shibler 
60759813Shibler #else /* not HAVE_SHM */
60859813Shibler 
60959813Shibler DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0,
61059813Shibler   "Dump current state of Emacs into executable file FILENAME.\n\
61159813Shibler Take symbols from SYMFILE (presumably the file you executed to run Emacs).")
61259813Shibler   (intoname, symname)
61359813Shibler      Lisp_Object intoname, symname;
61459813Shibler {
61559813Shibler   extern int my_edata;
61659813Shibler   Lisp_Object tem;
61759813Shibler   extern void malloc_warning ();
61859813Shibler 
61959813Shibler   CHECK_STRING (intoname, 0);
62059813Shibler   intoname = Fexpand_file_name (intoname, Qnil);
62159813Shibler   if (!NULL (symname))
62259813Shibler     {
62359813Shibler       CHECK_STRING (symname, 0);
62459813Shibler       if (XSTRING (symname)->size)
62559813Shibler 	symname = Fexpand_file_name (symname, Qnil);
62659813Shibler     }
62759813Shibler 
62859813Shibler   tem = Vpurify_flag;
62959813Shibler   Vpurify_flag = Qnil;
63059813Shibler 
63159813Shibler   fflush (stdout);
63259813Shibler #ifdef VMS
63359813Shibler   mapout_data (XSTRING (intoname)->data);
63459813Shibler #else
63559813Shibler   /* Tell malloc where start of impure now is */
63659813Shibler   /* Also arrange for warnings when nearly out of space.  */
63759813Shibler #ifndef SYSTEM_MALLOC
63859813Shibler   malloc_init (&my_edata, malloc_warning);
63959813Shibler #endif
64059813Shibler   unexec (XSTRING (intoname)->data,
64159813Shibler 	  !NULL (symname) ? XSTRING (symname)->data : 0, &my_edata, 0, 0);
64259813Shibler #endif /* not VMS */
64359813Shibler 
64459813Shibler   Vpurify_flag = tem;
64559813Shibler 
64659813Shibler   return Qnil;
64759813Shibler }
64859813Shibler 
64959813Shibler #endif /* not HAVE_SHM */
65059813Shibler 
65159813Shibler #endif /* not CANNOT_DUMP */
65259813Shibler 
65359813Shibler #ifdef VMS
65459813Shibler #define SEPCHAR ','
65559813Shibler #else
65659813Shibler #define SEPCHAR ':'
65759813Shibler #endif
65859813Shibler 
65959813Shibler Lisp_Object
decode_env_path(evarname,defalt)66059813Shibler decode_env_path (evarname, defalt)
66159813Shibler      char *evarname, *defalt;
66259813Shibler {
66359813Shibler   register char *path, *p;
66459813Shibler   extern char *index ();
66559813Shibler 
66659813Shibler   Lisp_Object lpath;
66759813Shibler 
66859813Shibler   path = (char *) egetenv (evarname);
66959813Shibler   if (!path)
67059813Shibler     path = defalt;
67159813Shibler   lpath = Qnil;
67259813Shibler   while (1)
67359813Shibler     {
67459813Shibler       p = index (path, SEPCHAR);
67559813Shibler       if (!p) p = path + strlen (path);
67659813Shibler       lpath = Fcons (p - path ? make_string (path, p - path) : Qnil,
67759813Shibler 		     lpath);
67859813Shibler       if (*p)
67959813Shibler 	path = p + 1;
68059813Shibler       else
68159813Shibler 	break;
68259813Shibler     }
68359813Shibler   return Fnreverse (lpath);
68459813Shibler }
68559813Shibler 
syms_of_emacs()68659813Shibler syms_of_emacs ()
68759813Shibler {
68859813Shibler #ifndef CANNOT_DUMP
68959813Shibler #ifdef HAVE_SHM
69059813Shibler   defsubr (&Sdump_emacs_data);
69159813Shibler #else
69259813Shibler   defsubr (&Sdump_emacs);
69359813Shibler #endif
69459813Shibler #endif /* not CANNOT_DUMP */
69559813Shibler 
69659813Shibler   defsubr (&Skill_emacs);
69759813Shibler 
69859813Shibler   DEFVAR_LISP ("command-line-args", &Vcommand_line_args,
69959813Shibler     "Args passed by shell to Emacs, as a list of strings.");
70059813Shibler 
70159813Shibler   DEFVAR_LISP ("system-type", &Vsystem_type,
70259813Shibler     "Symbol indicating type of operating system you are using.");
70359813Shibler   Vsystem_type = intern (SYSTEM_TYPE);
70459813Shibler 
70559813Shibler   DEFVAR_BOOL ("noninteractive", &noninteractive1,
70659813Shibler     "Non-nil means Emacs is running without interactive terminal.");
70759813Shibler 
70859813Shibler   Vkill_emacs_hook = Qnil;
70959813Shibler 
71059813Shibler   DEFVAR_LISP ("kill-emacs-hook", &Vkill_emacs_hook,
71159813Shibler     "Function called, if non-nil, whenever kill-emacs is called.");
71259813Shibler }
713