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