1*59813Shibler /* Fully extensible Emacs, running on Unix, intended for GNU.
2*59813Shibler    Copyright (C) 1985, 1986, 1987, 1990 Free Software Foundation, Inc.
3*59813Shibler 
4*59813Shibler This file is part of GNU Emacs.
5*59813Shibler 
6*59813Shibler GNU Emacs is free software; you can redistribute it and/or modify
7*59813Shibler it under the terms of the GNU General Public License as published by
8*59813Shibler the Free Software Foundation; either version 1, or (at your option)
9*59813Shibler any later version.
10*59813Shibler 
11*59813Shibler GNU Emacs is distributed in the hope that it will be useful,
12*59813Shibler but WITHOUT ANY WARRANTY; without even the implied warranty of
13*59813Shibler MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*59813Shibler GNU General Public License for more details.
15*59813Shibler 
16*59813Shibler You should have received a copy of the GNU General Public License
17*59813Shibler along with GNU Emacs; see the file COPYING.  If not, write to
18*59813Shibler the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19*59813Shibler 
20*59813Shibler 
21*59813Shibler #include <signal.h>
22*59813Shibler #include <errno.h>
23*59813Shibler 
24*59813Shibler #include "config.h"
25*59813Shibler #include <stdio.h>
26*59813Shibler #undef NULL
27*59813Shibler #include "lisp.h"
28*59813Shibler #include "commands.h"
29*59813Shibler 
30*59813Shibler #include <sys/types.h>
31*59813Shibler #include <sys/file.h>
32*59813Shibler 
33*59813Shibler #ifdef VMS
34*59813Shibler #include <ssdef.h>
35*59813Shibler #endif
36*59813Shibler 
37*59813Shibler #ifdef USG5
38*59813Shibler #include <fcntl.h>
39*59813Shibler #endif
40*59813Shibler 
41*59813Shibler #ifdef BSD
42*59813Shibler #include <sys/ioctl.h>
43*59813Shibler #endif
44*59813Shibler 
45*59813Shibler #ifdef APOLLO
46*59813Shibler #ifndef APOLLO_SR10
47*59813Shibler #include <default_acl.h>
48*59813Shibler #endif
49*59813Shibler #endif
50*59813Shibler 
51*59813Shibler #ifndef O_RDWR
52*59813Shibler #define O_RDWR 2
53*59813Shibler #endif
54*59813Shibler 
55*59813Shibler #define PRIO_PROCESS 0
56*59813Shibler 
57*59813Shibler /* Command line args from shell, as list of strings */
58*59813Shibler Lisp_Object Vcommand_line_args;
59*59813Shibler 
60*59813Shibler /* Hook run by `kill-emacs' before it does really anything.  */
61*59813Shibler Lisp_Object Vkill_emacs_hook;
62*59813Shibler 
63*59813Shibler /* Set nonzero after Emacs has started up the first time.
64*59813Shibler   Prevents reinitialization of the Lisp world and keymaps
65*59813Shibler   on subsequent starts.  */
66*59813Shibler int initialized;
67*59813Shibler 
68*59813Shibler /* Variable whose value is symbol giving operating system type */
69*59813Shibler Lisp_Object Vsystem_type;
70*59813Shibler 
71*59813Shibler /* If non-zero, emacs should not attempt to use an window-specific code,
72*59813Shibler    but instead should use the virtual terminal under which it was started */
73*59813Shibler int inhibit_window_system;
74*59813Shibler 
75*59813Shibler #ifdef HAVE_X_WINDOWS
76*59813Shibler /* If -d option is used, this variable points to the name of
77*59813Shibler    the display to use.  */
78*59813Shibler char *alternate_display;
79*59813Shibler char **xargv;
80*59813Shibler int xargc;
81*59813Shibler #endif /* HAVE_X_WINDOWS */
82*59813Shibler 
83*59813Shibler #ifdef USG_SHARED_LIBRARIES
84*59813Shibler /* If nonzero, this is the place to put the end of the writable segment
85*59813Shibler    at startup.  */
86*59813Shibler 
87*59813Shibler unsigned int bss_end = 0;
88*59813Shibler #endif
89*59813Shibler 
90*59813Shibler /* Nonzero means running Emacs without interactive terminal.  */
91*59813Shibler 
92*59813Shibler int noninteractive;
93*59813Shibler 
94*59813Shibler /* Value of Lisp variable `noninteractive'.
95*59813Shibler    Normally same as C variable `noninteractive'
96*59813Shibler    but nothing terrible happens if user sets this one.  */
97*59813Shibler 
98*59813Shibler int noninteractive1;
99*59813Shibler 
100*59813Shibler /* Signal code for the fatal signal that was received */
101*59813Shibler int fatal_error_code;
102*59813Shibler 
103*59813Shibler /* Nonzero if handling a fatal error already */
104*59813Shibler int fatal_error_in_progress;
105*59813Shibler 
106*59813Shibler /* Handle bus errors, illegal instruction, etc. */
107*59813Shibler fatal_error_signal (sig)
108*59813Shibler      int sig;
109*59813Shibler {
110*59813Shibler #ifdef BSD
111*59813Shibler   int tpgrp;
112*59813Shibler #endif /* BSD */
113*59813Shibler 
114*59813Shibler   fatal_error_code = sig;
115*59813Shibler   signal (sig, SIG_DFL);
116*59813Shibler 
117*59813Shibler   /* If fatal error occurs in code below, avoid infinite recursion.  */
118*59813Shibler   if (fatal_error_in_progress)
119*59813Shibler     kill (getpid (), fatal_error_code);
120*59813Shibler 
121*59813Shibler   fatal_error_in_progress = 1;
122*59813Shibler 
123*59813Shibler   /* If we are controlling the terminal, reset terminal modes */
124*59813Shibler #ifdef BSD
125*59813Shibler   if (ioctl(0, TIOCGPGRP, &tpgrp) == 0
126*59813Shibler       && tpgrp == getpgrp (0))
127*59813Shibler #endif /* BSD */
128*59813Shibler     {
129*59813Shibler       reset_sys_modes ();
130*59813Shibler       if (sig != SIGTERM)
131*59813Shibler 	fprintf (stderr, "Fatal error (%d).", sig);
132*59813Shibler     }
133*59813Shibler 
134*59813Shibler   /* Clean up */
135*59813Shibler #ifdef subprocesses
136*59813Shibler   kill_buffer_processes (Qnil);
137*59813Shibler #endif
138*59813Shibler   Fdo_auto_save (Qt);
139*59813Shibler 
140*59813Shibler #ifdef CLASH_DETECTION
141*59813Shibler   unlock_all_files ();
142*59813Shibler #endif /* CLASH_DETECTION */
143*59813Shibler 
144*59813Shibler #ifdef VMS
145*59813Shibler   kill_vms_processes ();
146*59813Shibler   LIB$STOP (SS$_ABORT);
147*59813Shibler #else
148*59813Shibler   /* Signal the same code; this time it will really be fatal.  */
149*59813Shibler   kill (getpid (), fatal_error_code);
150*59813Shibler #endif /* not VMS */
151*59813Shibler }
152*59813Shibler 
153*59813Shibler /* Code for dealing with Lisp access to the Unix command line */
154*59813Shibler 
155*59813Shibler static
156*59813Shibler init_cmdargs (argc, argv, skip_args)
157*59813Shibler      int argc;
158*59813Shibler      char **argv;
159*59813Shibler      int skip_args;
160*59813Shibler {
161*59813Shibler   register int i;
162*59813Shibler 
163*59813Shibler   Vcommand_line_args = Qnil;
164*59813Shibler 
165*59813Shibler   for (i = argc - 1; i >= 0; i--)
166*59813Shibler     {
167*59813Shibler       if (i == 0 || i > skip_args)
168*59813Shibler 	Vcommand_line_args
169*59813Shibler 	  = Fcons (build_string (argv[i]), Vcommand_line_args);
170*59813Shibler     }
171*59813Shibler }
172*59813Shibler 
173*59813Shibler #ifdef VMS
174*59813Shibler #ifdef LINK_CRTL_SHARE
175*59813Shibler #ifdef SHAREABLE_LIB_BUG
176*59813Shibler extern noshare char **environ;
177*59813Shibler #endif /* SHAREABLE_LIB_BUG */
178*59813Shibler #endif /* LINK_CRTL_SHARE */
179*59813Shibler #endif /* VMS */
180*59813Shibler 
181*59813Shibler /* ARGSUSED */
182*59813Shibler main (argc, argv, envp)
183*59813Shibler      int argc;
184*59813Shibler      char **argv;
185*59813Shibler      char **envp;
186*59813Shibler {
187*59813Shibler   int skip_args = 0;
188*59813Shibler   extern int errno;
189*59813Shibler   extern void malloc_warning ();
190*59813Shibler 
191*59813Shibler /* Map in shared memory, if we are using that.  */
192*59813Shibler #ifdef HAVE_SHM
193*59813Shibler   if (argc > 1 && !strcmp (argv[1], "-nl"))
194*59813Shibler     {
195*59813Shibler       map_in_data (0);
196*59813Shibler       /* The shared momory was just restored, which clobbered this.  */
197*59813Shibler       skip_args = 1;
198*59813Shibler     }
199*59813Shibler   else
200*59813Shibler     {
201*59813Shibler       map_in_data (1);
202*59813Shibler       /* The shared momory was just restored, which clobbered this.  */
203*59813Shibler       skip_args = 0;
204*59813Shibler     }
205*59813Shibler #endif
206*59813Shibler 
207*59813Shibler #ifdef VMS
208*59813Shibler   /* If -map specified, map the data file in */
209*59813Shibler   if (argc > 2 && ! strcmp (argv[1], "-map"))
210*59813Shibler     {
211*59813Shibler       skip_args = 2;
212*59813Shibler       mapin_data (argv[2]);
213*59813Shibler     }
214*59813Shibler 
215*59813Shibler #ifdef LINK_CRTL_SHARE
216*59813Shibler #ifdef SHAREABLE_LIB_BUG
217*59813Shibler   /* Bletcherous shared libraries! */
218*59813Shibler   if (!stdin)
219*59813Shibler     stdin = fdopen (0, "r");
220*59813Shibler   if (!stdout)
221*59813Shibler     stdout = fdopen (1, "w");
222*59813Shibler   if (!stderr)
223*59813Shibler     stderr = fdopen (2, "w");
224*59813Shibler   if (!environ)
225*59813Shibler     environ = envp;
226*59813Shibler #endif /* SHAREABLE_LIB_BUG */
227*59813Shibler #endif /* LINK_CRTL_SHARE */
228*59813Shibler #endif /* VMS */
229*59813Shibler 
230*59813Shibler #ifdef USG_SHARED_LIBRARIES
231*59813Shibler   if (bss_end)
232*59813Shibler     brk (bss_end);
233*59813Shibler #endif
234*59813Shibler 
235*59813Shibler   clearerr (stdin);
236*59813Shibler 
237*59813Shibler #ifdef APOLLO
238*59813Shibler #ifndef APOLLO_SR10
239*59813Shibler   /* If USE_DOMAIN_ACLS environment variable exists,
240*59813Shibler      use ACLs rather than UNIX modes. */
241*59813Shibler   if (egetenv ("USE_DOMAIN_ACLS"))
242*59813Shibler     default_acl (USE_DEFACL);
243*59813Shibler #endif
244*59813Shibler #endif /* APOLLO */
245*59813Shibler 
246*59813Shibler #ifndef SYSTEM_MALLOC
247*59813Shibler   /* Arrange for warnings when nearly out of space.  */
248*59813Shibler   malloc_init (0, malloc_warning);
249*59813Shibler #endif
250*59813Shibler 
251*59813Shibler #ifdef HIGHPRI
252*59813Shibler   setpriority (PRIO_PROCESS, getpid (), HIGHPRI);
253*59813Shibler   setuid (getuid ());
254*59813Shibler #endif HIGHPRI
255*59813Shibler 
256*59813Shibler   inhibit_window_system = 0;
257*59813Shibler 
258*59813Shibler #ifdef HAVE_X_WINDOWS
259*59813Shibler   xargv = argv;
260*59813Shibler   xargc = argc;
261*59813Shibler #endif
262*59813Shibler 
263*59813Shibler /* Handle the -t switch, which specifies filename to use as terminal */
264*59813Shibler   if (skip_args + 2 < argc && !strcmp (argv[skip_args + 1], "-t"))
265*59813Shibler     {
266*59813Shibler       skip_args += 2;
267*59813Shibler       close (0);
268*59813Shibler       close (1);
269*59813Shibler       open (argv[skip_args], O_RDWR, 2 );
270*59813Shibler       dup (0);
271*59813Shibler       fprintf (stderr, "Using %s\n", argv[skip_args]);
272*59813Shibler #ifdef HAVE_X_WINDOWS
273*59813Shibler       inhibit_window_system = 1;	/* -t => -nw */
274*59813Shibler #endif
275*59813Shibler     }
276*59813Shibler #ifdef HAVE_X_WINDOWS
277*59813Shibler /* Handle the -d switch, which means use a different display for X */
278*59813Shibler   if (skip_args + 2 < argc && (!strcmp (argv[skip_args + 1], "-d") ||
279*59813Shibler 			       !strcmp (argv[skip_args + 1], "-display")))
280*59813Shibler     {
281*59813Shibler       skip_args += 2;
282*59813Shibler       alternate_display = argv[skip_args];
283*59813Shibler     }
284*59813Shibler   else
285*59813Shibler     alternate_display = 0;
286*59813Shibler #endif	/* HAVE_X_WINDOWS */
287*59813Shibler 
288*59813Shibler   if (skip_args + 1 < argc
289*59813Shibler       && (!strcmp (argv[skip_args + 1], "-nw")))
290*59813Shibler     {
291*59813Shibler       skip_args += 1;
292*59813Shibler       inhibit_window_system = 1;
293*59813Shibler     }
294*59813Shibler 
295*59813Shibler /* Handle the -batch switch, which means don't do interactive display.  */
296*59813Shibler   noninteractive = 0;
297*59813Shibler   if (skip_args + 1 < argc && !strcmp (argv[skip_args + 1], "-batch"))
298*59813Shibler     {
299*59813Shibler       skip_args += 1;
300*59813Shibler       noninteractive = 1;
301*59813Shibler     }
302*59813Shibler 
303*59813Shibler   if (
304*59813Shibler #ifndef CANNOT_DUMP
305*59813Shibler       ! noninteractive || initialized
306*59813Shibler #else
307*59813Shibler       1
308*59813Shibler #endif
309*59813Shibler       )
310*59813Shibler     {
311*59813Shibler       /* Don't catch these signals in batch mode if not initialized.
312*59813Shibler 	 On some machines, this sets static data that would make
313*59813Shibler 	 signal fail to work right when the dumped Emacs is run.  */
314*59813Shibler       signal (SIGHUP, fatal_error_signal);
315*59813Shibler       signal (SIGQUIT, fatal_error_signal);
316*59813Shibler       signal (SIGILL, fatal_error_signal);
317*59813Shibler       signal (SIGTRAP, fatal_error_signal);
318*59813Shibler       signal (SIGIOT, fatal_error_signal);
319*59813Shibler #ifdef SIGEMT
320*59813Shibler       signal (SIGEMT, fatal_error_signal);
321*59813Shibler #endif
322*59813Shibler       signal (SIGFPE, fatal_error_signal);
323*59813Shibler       signal (SIGBUS, fatal_error_signal);
324*59813Shibler       signal (SIGSEGV, fatal_error_signal);
325*59813Shibler       signal (SIGSYS, fatal_error_signal);
326*59813Shibler       signal (SIGTERM, fatal_error_signal);
327*59813Shibler #ifdef SIGXCPU
328*59813Shibler       signal (SIGXCPU, fatal_error_signal);
329*59813Shibler #endif
330*59813Shibler #ifdef SIGXFSZ
331*59813Shibler       signal (SIGXFSZ, fatal_error_signal);
332*59813Shibler #endif SIGXFSZ
333*59813Shibler 
334*59813Shibler #ifdef AIX
335*59813Shibler       signal (SIGDANGER, fatal_error_signal);
336*59813Shibler       signal (20, fatal_error_signal);
337*59813Shibler       signal (21, fatal_error_signal);
338*59813Shibler       signal (22, fatal_error_signal);
339*59813Shibler       signal (23, fatal_error_signal);
340*59813Shibler       signal (24, fatal_error_signal);
341*59813Shibler       signal (SIGAIO, fatal_error_signal);
342*59813Shibler       signal (SIGPTY, fatal_error_signal);
343*59813Shibler       signal (SIGIOINT, fatal_error_signal);
344*59813Shibler       signal (SIGGRANT, fatal_error_signal);
345*59813Shibler       signal (SIGRETRACT, fatal_error_signal);
346*59813Shibler       signal (SIGSOUND, fatal_error_signal);
347*59813Shibler       signal (SIGMSG, fatal_error_signal);
348*59813Shibler #endif /* AIX */
349*59813Shibler     }
350*59813Shibler 
351*59813Shibler   noninteractive1 = noninteractive;
352*59813Shibler 
353*59813Shibler /* Perform basic initializations (not merely interning symbols) */
354*59813Shibler 
355*59813Shibler   if (!initialized)
356*59813Shibler     {
357*59813Shibler       init_alloc_once ();
358*59813Shibler       init_obarray ();
359*59813Shibler       init_eval_once ();
360*59813Shibler       init_syntax_once ();	/* Create standard syntax table.  */
361*59813Shibler 		      /* Must be done before init_buffer */
362*59813Shibler       init_buffer_once ();	/* Create buffer table and some buffers */
363*59813Shibler       init_minibuf_once ();	/* Create list of minibuffers */
364*59813Shibler 			      /* Must precede init_window_once */
365*59813Shibler       init_window_once ();	/* Init the window system */
366*59813Shibler     }
367*59813Shibler 
368*59813Shibler   init_alloc ();
369*59813Shibler #ifdef MAINTAIN_ENVIRONMENT
370*59813Shibler   init_environ ();
371*59813Shibler #endif
372*59813Shibler   init_eval ();
373*59813Shibler   init_data ();
374*59813Shibler   init_read ();
375*59813Shibler 
376*59813Shibler   init_cmdargs (argc, argv, skip_args);	/* Create list Vcommand_line_args */
377*59813Shibler   init_buffer ();	/* Init default directory of main buffer */
378*59813Shibler   if (!noninteractive)
379*59813Shibler     {
380*59813Shibler #ifdef VMS
381*59813Shibler       init_vms_input ();/* init_display calls get_screen_size, that needs this */
382*59813Shibler #endif /* VMS */
383*59813Shibler       init_display ();	/* Determine terminal type.  init_sys_modes uses results */
384*59813Shibler     }
385*59813Shibler   init_keyboard ();	/* This too must precede init_sys_modes */
386*59813Shibler   init_callproc ();	/* And this too. */
387*59813Shibler   init_sys_modes ();	/* Init system terminal modes (RAW or CBREAK, etc.) */
388*59813Shibler   init_xdisp ();
389*59813Shibler   init_macros ();
390*59813Shibler   init_editfns ();
391*59813Shibler #ifdef VMS
392*59813Shibler   init_vmsfns ();
393*59813Shibler #endif /* VMS */
394*59813Shibler #ifdef subprocesses
395*59813Shibler   init_process ();
396*59813Shibler #endif /* subprocesses */
397*59813Shibler 
398*59813Shibler /* Intern the names of all standard functions and variables; define standard keys */
399*59813Shibler 
400*59813Shibler   if (!initialized)
401*59813Shibler     {
402*59813Shibler       /* The basic levels of Lisp must come first */
403*59813Shibler       /* And data must come first of all
404*59813Shibler 	 for the sake of symbols like error-message */
405*59813Shibler       syms_of_data ();
406*59813Shibler       syms_of_alloc ();
407*59813Shibler #ifdef MAINTAIN_ENVIRONMENT
408*59813Shibler       syms_of_environ ();
409*59813Shibler #endif MAINTAIN_ENVIRONMENT
410*59813Shibler       syms_of_read ();
411*59813Shibler       syms_of_print ();
412*59813Shibler       syms_of_eval ();
413*59813Shibler       syms_of_fns ();
414*59813Shibler 
415*59813Shibler       syms_of_abbrev ();
416*59813Shibler       syms_of_buffer ();
417*59813Shibler       syms_of_bytecode ();
418*59813Shibler       syms_of_callint ();
419*59813Shibler       syms_of_casefiddle ();
420*59813Shibler       syms_of_callproc ();
421*59813Shibler       syms_of_cmds ();
422*59813Shibler #ifndef NO_DIR_LIBRARY
423*59813Shibler       syms_of_dired ();
424*59813Shibler #endif /* not NO_DIR_LIBRARY */
425*59813Shibler       syms_of_display ();
426*59813Shibler       syms_of_doc ();
427*59813Shibler       syms_of_editfns ();
428*59813Shibler       syms_of_emacs ();
429*59813Shibler       syms_of_fileio ();
430*59813Shibler #ifdef CLASH_DETECTION
431*59813Shibler       syms_of_filelock ();
432*59813Shibler #endif /* CLASH_DETECTION */
433*59813Shibler       syms_of_indent ();
434*59813Shibler       syms_of_keyboard ();
435*59813Shibler       syms_of_keymap ();
436*59813Shibler       syms_of_macros ();
437*59813Shibler       syms_of_marker ();
438*59813Shibler       syms_of_minibuf ();
439*59813Shibler       syms_of_mocklisp ();
440*59813Shibler #ifdef subprocesses
441*59813Shibler       syms_of_process ();
442*59813Shibler #endif /* subprocesses */
443*59813Shibler       syms_of_search ();
444*59813Shibler       syms_of_syntax ();
445*59813Shibler       syms_of_undo ();
446*59813Shibler       syms_of_window ();
447*59813Shibler       syms_of_xdisp ();
448*59813Shibler #ifdef HAVE_X_WINDOWS
449*59813Shibler       syms_of_xfns ();
450*59813Shibler #ifdef HAVE_X_MENU
451*59813Shibler       syms_of_xmenu ();
452*59813Shibler #endif /* HAVE_X_MENU */
453*59813Shibler #endif /* HAVE_X_WINDOWS */
454*59813Shibler 
455*59813Shibler #ifdef SYMS_SYSTEM
456*59813Shibler       SYMS_SYSTEM;
457*59813Shibler #endif
458*59813Shibler 
459*59813Shibler #ifdef SYMS_MACHINE
460*59813Shibler       SYMS_MACHINE;
461*59813Shibler #endif
462*59813Shibler 
463*59813Shibler       keys_of_casefiddle ();
464*59813Shibler       keys_of_cmds ();
465*59813Shibler       keys_of_buffer ();
466*59813Shibler       keys_of_keyboard ();
467*59813Shibler       keys_of_keymap ();
468*59813Shibler       keys_of_macros ();
469*59813Shibler       keys_of_minibuf ();
470*59813Shibler       keys_of_window ();
471*59813Shibler     }
472*59813Shibler 
473*59813Shibler   if (!initialized)
474*59813Shibler     {
475*59813Shibler       /* Handle -l loadup-and-dump, args passed by Makefile. */
476*59813Shibler       if (argc > 2 + skip_args && !strcmp (argv[1 + skip_args], "-l"))
477*59813Shibler 	Vtop_level = Fcons (intern ("load"),
478*59813Shibler 			    Fcons (build_string (argv[2 + skip_args]), Qnil));
479*59813Shibler #ifdef CANNOT_DUMP
480*59813Shibler       /* Unless next switch is -nl, load "loadup.el" first thing.  */
481*59813Shibler       if (!(argc > 1 + skip_args && !strcmp (argv[1 + skip_args], "-nl")))
482*59813Shibler 	Vtop_level = Fcons (intern ("load"),
483*59813Shibler 			    Fcons (build_string ("loadup.el"), Qnil));
484*59813Shibler #endif /* CANNOT_DUMP */
485*59813Shibler     }
486*59813Shibler 
487*59813Shibler   initialized = 1;
488*59813Shibler 
489*59813Shibler   /* Enter editor command loop.  This never returns.  */
490*59813Shibler   Frecursive_edit ();
491*59813Shibler   /* NOTREACHED */
492*59813Shibler }
493*59813Shibler 
494*59813Shibler DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P",
495*59813Shibler   "Exit the Emacs job and kill it.  ARG means no query.\n\
496*59813Shibler If emacs is running noninteractively and ARG is an integer,\n\
497*59813Shibler return ARG as the exit program code.")
498*59813Shibler   (arg)
499*59813Shibler      Lisp_Object arg;
500*59813Shibler {
501*59813Shibler   Lisp_Object answer;
502*59813Shibler   int i;
503*59813Shibler   struct gcpro gcpro1;
504*59813Shibler 
505*59813Shibler   GCPRO1 (arg);
506*59813Shibler 
507*59813Shibler   if (!NULL (Vkill_emacs_hook))
508*59813Shibler     call0 (Vkill_emacs_hook);
509*59813Shibler 
510*59813Shibler   if (feof (stdin))
511*59813Shibler     arg = Qt;
512*59813Shibler 
513*59813Shibler #ifdef subprocesses
514*59813Shibler   kill_buffer_processes (Qnil);
515*59813Shibler #endif /* subprocesses */
516*59813Shibler 
517*59813Shibler #ifdef VMS
518*59813Shibler   kill_vms_processes ();
519*59813Shibler #endif /* VMS */
520*59813Shibler 
521*59813Shibler   Fdo_auto_save (Qt);
522*59813Shibler 
523*59813Shibler #ifdef CLASH_DETECTION
524*59813Shibler   unlock_all_files ();
525*59813Shibler #endif /* CLASH_DETECTION */
526*59813Shibler 
527*59813Shibler   fflush (stdout);
528*59813Shibler   reset_sys_modes ();
529*59813Shibler   UNGCPRO;
530*59813Shibler 
531*59813Shibler /* Is it really necessary to do this deassign
532*59813Shibler    when we are going to exit anyway?  */
533*59813Shibler /* #ifdef VMS
534*59813Shibler   stop_vms_input ();
535*59813Shibler  #endif  */
536*59813Shibler   stuff_buffered_input (arg);
537*59813Shibler #ifdef SIGIO
538*59813Shibler   /* There is a tendency for a SIGIO signal to arrive within exit,
539*59813Shibler      and cause a SIGHUP because the input descriptor is already closed.  */
540*59813Shibler   unrequest_sigio ();
541*59813Shibler   signal (SIGIO, SIG_IGN);
542*59813Shibler #endif
543*59813Shibler   exit ((XTYPE (arg) == Lisp_Int) ? XINT (arg)
544*59813Shibler #ifdef VMS
545*59813Shibler 	: 1
546*59813Shibler #else
547*59813Shibler 	: 0
548*59813Shibler #endif
549*59813Shibler 	);
550*59813Shibler   /* NOTREACHED */
551*59813Shibler }
552*59813Shibler 
553*59813Shibler #ifndef CANNOT_DUMP
554*59813Shibler /* Nothing like this can be implemented on an Apollo.
555*59813Shibler    What a loss!  */
556*59813Shibler 
557*59813Shibler #ifdef HAVE_SHM
558*59813Shibler 
559*59813Shibler DEFUN ("dump-emacs-data", Fdump_emacs_data, Sdump_emacs_data, 1, 1, 0,
560*59813Shibler   "Dump current state of Emacs into data file FILENAME.\n\
561*59813Shibler This function exists on systems that use HAVE_SHM.")
562*59813Shibler   (intoname)
563*59813Shibler      Lisp_Object intoname;
564*59813Shibler {
565*59813Shibler   extern int my_edata;
566*59813Shibler   Lisp_Object tem;
567*59813Shibler   extern void malloc_warning ();
568*59813Shibler 
569*59813Shibler   CHECK_STRING (intoname, 0);
570*59813Shibler   intoname = Fexpand_file_name (intoname, Qnil);
571*59813Shibler 
572*59813Shibler   tem = Vpurify_flag;
573*59813Shibler   Vpurify_flag = Qnil;
574*59813Shibler 
575*59813Shibler   fflush (stdout);
576*59813Shibler   /* Tell malloc where start of impure now is */
577*59813Shibler   /* Also arrange for warnings when nearly out of space.  */
578*59813Shibler #ifndef SYSTEM_MALLOC
579*59813Shibler   malloc_init (&my_edata, malloc_warning);
580*59813Shibler #endif
581*59813Shibler   map_out_data (XSTRING (intoname)->data);
582*59813Shibler 
583*59813Shibler   Vpurify_flag = tem;
584*59813Shibler 
585*59813Shibler   return Qnil;
586*59813Shibler }
587*59813Shibler 
588*59813Shibler #else /* not HAVE_SHM */
589*59813Shibler 
590*59813Shibler DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0,
591*59813Shibler   "Dump current state of Emacs into executable file FILENAME.\n\
592*59813Shibler Take symbols from SYMFILE (presumably the file you executed to run Emacs).")
593*59813Shibler   (intoname, symname)
594*59813Shibler      Lisp_Object intoname, symname;
595*59813Shibler {
596*59813Shibler   extern int my_edata;
597*59813Shibler   Lisp_Object tem;
598*59813Shibler   extern void malloc_warning ();
599*59813Shibler 
600*59813Shibler   CHECK_STRING (intoname, 0);
601*59813Shibler   intoname = Fexpand_file_name (intoname, Qnil);
602*59813Shibler   if (!NULL (symname))
603*59813Shibler     {
604*59813Shibler       CHECK_STRING (symname, 0);
605*59813Shibler       if (XSTRING (symname)->size)
606*59813Shibler 	symname = Fexpand_file_name (symname, Qnil);
607*59813Shibler     }
608*59813Shibler 
609*59813Shibler   tem = Vpurify_flag;
610*59813Shibler   Vpurify_flag = Qnil;
611*59813Shibler 
612*59813Shibler   fflush (stdout);
613*59813Shibler #ifdef VMS
614*59813Shibler   mapout_data (XSTRING (intoname)->data);
615*59813Shibler #else
616*59813Shibler   /* Tell malloc where start of impure now is */
617*59813Shibler   /* Also arrange for warnings when nearly out of space.  */
618*59813Shibler #ifndef SYSTEM_MALLOC
619*59813Shibler   malloc_init (&my_edata, malloc_warning);
620*59813Shibler #endif
621*59813Shibler   unexec (XSTRING (intoname)->data,
622*59813Shibler 	  !NULL (symname) ? XSTRING (symname)->data : 0, &my_edata, 0, 0);
623*59813Shibler #endif /* not VMS */
624*59813Shibler 
625*59813Shibler   Vpurify_flag = tem;
626*59813Shibler 
627*59813Shibler   return Qnil;
628*59813Shibler }
629*59813Shibler 
630*59813Shibler #endif /* not HAVE_SHM */
631*59813Shibler 
632*59813Shibler #endif /* not CANNOT_DUMP */
633*59813Shibler 
634*59813Shibler #ifdef VMS
635*59813Shibler #define SEPCHAR ','
636*59813Shibler #else
637*59813Shibler #define SEPCHAR ':'
638*59813Shibler #endif
639*59813Shibler 
640*59813Shibler Lisp_Object
641*59813Shibler decode_env_path (evarname, defalt)
642*59813Shibler      char *evarname, *defalt;
643*59813Shibler {
644*59813Shibler   register char *path, *p;
645*59813Shibler   extern char *index ();
646*59813Shibler 
647*59813Shibler   Lisp_Object lpath;
648*59813Shibler 
649*59813Shibler   path = (char *) egetenv (evarname);
650*59813Shibler   if (!path)
651*59813Shibler     path = defalt;
652*59813Shibler   lpath = Qnil;
653*59813Shibler   while (1)
654*59813Shibler     {
655*59813Shibler       p = index (path, SEPCHAR);
656*59813Shibler       if (!p) p = path + strlen (path);
657*59813Shibler       lpath = Fcons (p - path ? make_string (path, p - path) : Qnil,
658*59813Shibler 		     lpath);
659*59813Shibler       if (*p)
660*59813Shibler 	path = p + 1;
661*59813Shibler       else
662*59813Shibler 	break;
663*59813Shibler     }
664*59813Shibler   return Fnreverse (lpath);
665*59813Shibler }
666*59813Shibler 
667*59813Shibler syms_of_emacs ()
668*59813Shibler {
669*59813Shibler #ifndef CANNOT_DUMP
670*59813Shibler #ifdef HAVE_SHM
671*59813Shibler   defsubr (&Sdump_emacs_data);
672*59813Shibler #else
673*59813Shibler   defsubr (&Sdump_emacs);
674*59813Shibler #endif
675*59813Shibler #endif /* not CANNOT_DUMP */
676*59813Shibler 
677*59813Shibler   defsubr (&Skill_emacs);
678*59813Shibler 
679*59813Shibler   DEFVAR_LISP ("command-line-args", &Vcommand_line_args,
680*59813Shibler     "Args passed by shell to Emacs, as a list of strings.");
681*59813Shibler 
682*59813Shibler   DEFVAR_LISP ("system-type", &Vsystem_type,
683*59813Shibler     "Symbol indicating type of operating system you are using.");
684*59813Shibler   Vsystem_type = intern (SYSTEM_TYPE);
685*59813Shibler 
686*59813Shibler   DEFVAR_BOOL ("noninteractive", &noninteractive1,
687*59813Shibler     "Non-nil means Emacs is running without interactive terminal.");
688*59813Shibler 
689*59813Shibler   Vkill_emacs_hook = Qnil;
690*59813Shibler 
691*59813Shibler   DEFVAR_LISP ("kill-emacs-hook", &Vkill_emacs_hook,
692*59813Shibler     "Function called, if non-nil, whenever kill-emacs is called.");
693*59813Shibler }
694