Comment change.
[bpt/emacs.git] / src / emacs.c
CommitLineData
f927c5ae 1/* Fully extensible Emacs, running on Unix, intended for GNU.
f8c25f1b 2 Copyright (C) 1985, 86, 87, 93, 94, 95 Free Software Foundation, Inc.
f927c5ae
JB
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
40be253a 8the Free Software Foundation; either version 2, or (at your option)
f927c5ae
JB
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21#include <signal.h>
22#include <errno.h>
23
18160b98 24#include <config.h>
f927c5ae
JB
25#include <stdio.h>
26
27#include <sys/types.h>
28#include <sys/file.h>
29
30#ifdef VMS
31#include <ssdef.h>
32#endif
33
f927c5ae
JB
34#ifdef BSD
35#include <sys/ioctl.h>
36#endif
37
f927c5ae
JB
38#include "lisp.h"
39#include "commands.h"
bef79ee4 40#include "intervals.h"
f927c5ae 41
edc8ae07 42#include "systty.h"
8090eb09 43#include "syssignal.h"
6c362a8b 44#include "process.h"
a41f8bed 45
f927c5ae
JB
46#ifndef O_RDWR
47#define O_RDWR 2
48#endif
49
43165242
KH
50extern void malloc_warning ();
51extern char *index ();
52extern char *strerror ();
53
f927c5ae
JB
54/* Command line args from shell, as list of strings */
55Lisp_Object Vcommand_line_args;
56
59653951
JB
57/* The name under which Emacs was invoked, with any leading directory
58 names discarded. */
59Lisp_Object Vinvocation_name;
60
ace40a69
RS
61/* The directory name from which Emacs was invoked. */
62Lisp_Object Vinvocation_directory;
63
07f4d123
RS
64/* The directory name in which to find subdirs such as lisp and etc.
65 nil means get them only from PATH_LOADSEARCH. */
66Lisp_Object Vinstallation_directory;
67
e5d77022
JB
68/* Hook run by `kill-emacs' before it does really anything. */
69Lisp_Object Vkill_emacs_hook;
70
f927c5ae
JB
71/* Set nonzero after Emacs has started up the first time.
72 Prevents reinitialization of the Lisp world and keymaps
73 on subsequent starts. */
74int initialized;
75
271c7b7c 76/* Variable whose value is symbol giving operating system type. */
f927c5ae 77Lisp_Object Vsystem_type;
271c7b7c
RS
78
79/* Variable whose value is string giving configuration built for. */
80Lisp_Object Vsystem_configuration;
f0fc0b1a
KH
81
82/* Variable whose value is string giving configuration options,
83 for use when reporting bugs. */
84Lisp_Object Vsystem_configuration_options;
85
f927c5ae
JB
86/* If non-zero, emacs should not attempt to use an window-specific code,
87 but instead should use the virtual terminal under which it was started */
88int inhibit_window_system;
89
5aa7f46a
JB
90/* If nonzero, set Emacs to run at this priority. This is also used
91 in child_setup and sys_suspend to make sure subshells run at normal
92 priority; Those functions have their own extern declaration. */
3005da00
RS
93int emacs_priority;
94
7074fde6
FP
95/* If non-zero a filter or a sentinel is running. Tested to save the match
96 data on the first attempt to change it inside asynchronous code. */
97int running_asynch_code;
98
647cec74 99#ifdef BSD_PGRPS
9ae8f997
JB
100/* See sysdep.c. */
101extern int inherited_pgroup;
102#endif
103
f927c5ae
JB
104#ifdef HAVE_X_WINDOWS
105/* If non-zero, -d was specified, meaning we're using some window system. */
106int display_arg;
107#endif
108
109/* An address near the bottom of the stack.
110 Tells GC how to save a copy of the stack. */
111char *stack_bottom;
112
8ba50e1a 113#ifdef HAVE_WINDOW_SYSTEM
f927c5ae 114extern Lisp_Object Vwindow_system;
8ba50e1a 115#endif /* HAVE_WINDOW_SYSTEM */
f927c5ae 116
1090a161
RS
117extern Lisp_Object Vauto_save_list_file_name;
118
f927c5ae
JB
119#ifdef USG_SHARED_LIBRARIES
120/* If nonzero, this is the place to put the end of the writable segment
121 at startup. */
122
123unsigned int bss_end = 0;
124#endif
125
126/* Nonzero means running Emacs without interactive terminal. */
127
128int noninteractive;
129
130/* Value of Lisp variable `noninteractive'.
131 Normally same as C variable `noninteractive'
132 but nothing terrible happens if user sets this one. */
133
134int noninteractive1;
e29f86e4
RS
135
136/* Save argv and argc. */
137char **initial_argv;
138int initial_argc;
081bef73
RS
139
140static void sort_args ();
f927c5ae
JB
141\f
142/* Signal code for the fatal signal that was received */
143int fatal_error_code;
144
145/* Nonzero if handling a fatal error already */
146int fatal_error_in_progress;
147
148/* Handle bus errors, illegal instruction, etc. */
2447c626 149SIGTYPE
f927c5ae
JB
150fatal_error_signal (sig)
151 int sig;
152{
f927c5ae
JB
153 fatal_error_code = sig;
154 signal (sig, SIG_DFL);
155
156 /* If fatal error occurs in code below, avoid infinite recursion. */
8090eb09
JB
157 if (! fatal_error_in_progress)
158 {
159 fatal_error_in_progress = 1;
f927c5ae 160
f7ab4e3d 161 shut_down_emacs (sig, 0, Qnil);
8090eb09 162 }
f927c5ae
JB
163
164#ifdef VMS
f927c5ae
JB
165 LIB$STOP (SS$_ABORT);
166#else
8090eb09
JB
167 /* Signal the same code; this time it will really be fatal.
168 Remember that since we're in a signal handler, the signal we're
169 going to send is probably blocked, so we have to unblock it if we
170 want to really receive it. */
29b89fe0 171#ifndef MSDOS
a90538cb 172 sigunblock (sigmask (fatal_error_code));
29b89fe0 173#endif
f927c5ae
JB
174 kill (getpid (), fatal_error_code);
175#endif /* not VMS */
176}
271c7b7c
RS
177
178#ifdef SIGDANGER
179
16c323ee 180/* Handler for SIGDANGER. */
271c7b7c
RS
181SIGTYPE
182memory_warning_signal (sig)
183 int sig;
184{
185 signal (sig, memory_warning_signal);
186
187 malloc_warning ("Operating system warns that virtual memory is running low.\n");
55796183
RS
188
189 /* It might be unsafe to call do_auto_save now. */
190 force_auto_save_soon ();
271c7b7c
RS
191}
192#endif
f927c5ae
JB
193\f
194/* Code for dealing with Lisp access to the Unix command line */
195
196static
197init_cmdargs (argc, argv, skip_args)
198 int argc;
199 char **argv;
200 int skip_args;
201{
202 register int i;
07f4d123 203 Lisp_Object name, dir;
f927c5ae 204
e29f86e4
RS
205 initial_argv = argv;
206 initial_argc = argc;
207
cb421be8 208 Vinvocation_name = Ffile_name_nondirectory (build_string (argv[0]));
ace40a69
RS
209 Vinvocation_directory = Ffile_name_directory (build_string (argv[0]));
210 /* If we got no directory in argv[0], search PATH to find where
211 Emacs actually came from. */
212 if (NILP (Vinvocation_directory))
213 {
214 Lisp_Object found;
215 int yes = openp (Vexec_path, Vinvocation_name,
6c362a8b 216 EXEC_SUFFIXES, &found, 1);
e443f843 217 if (yes == 1)
ace40a69
RS
218 Vinvocation_directory = Ffile_name_directory (found);
219 }
59653951 220
4133b300
RS
221 if (!NILP (Vinvocation_directory)
222 && NILP (Ffile_name_absolute_p (Vinvocation_directory)))
223 /* Emacs was started with relative path, like ./emacs */
224 Vinvocation_directory = Fexpand_file_name (Vinvocation_directory, Qnil);
225
07f4d123
RS
226 Vinstallation_directory = Qnil;
227
228 if (!NILP (Vinvocation_directory))
229 {
230 dir = Vinvocation_directory;
231 name = Fexpand_file_name (Vinvocation_name, dir);
232 while (1)
233 {
f5ab9736 234 Lisp_Object tem, lib_src_exists;
07f4d123
RS
235 Lisp_Object etc_exists, info_exists;
236
f5ab9736
RS
237 /* See if dir contains subdirs for use by Emacs.
238 Check for the ones that would exist in a build directory,
239 not including lisp and info. */
240 tem = Fexpand_file_name (build_string ("lib-src"), dir);
241 lib_src_exists = Ffile_exists_p (tem);
242 if (!NILP (lib_src_exists))
07f4d123 243 {
f5ab9736
RS
244 tem = Fexpand_file_name (build_string ("etc"), dir);
245 etc_exists = Ffile_exists_p (tem);
246 if (!NILP (etc_exists))
07f4d123 247 {
f5ab9736
RS
248 Vinstallation_directory
249 = Ffile_name_as_directory (dir);
250 break;
07f4d123
RS
251 }
252 }
253
254 /* See if dir's parent contains those subdirs. */
f5ab9736
RS
255 tem = Fexpand_file_name (build_string ("../lib-src"), dir);
256 lib_src_exists = Ffile_exists_p (tem);
257 if (!NILP (lib_src_exists))
07f4d123 258 {
f5ab9736
RS
259 tem = Fexpand_file_name (build_string ("../etc"), dir);
260 etc_exists = Ffile_exists_p (tem);
261 if (!NILP (etc_exists))
07f4d123 262 {
f5ab9736
RS
263 tem = Fexpand_file_name (build_string (".."), dir);
264 Vinstallation_directory
265 = Ffile_name_as_directory (tem);
266 break;
07f4d123
RS
267 }
268 }
269
270 /* If the Emacs executable is actually a link,
271 next try the dir that the link points into. */
272 tem = Ffile_symlink_p (name);
273 if (!NILP (tem))
274 {
260ec24d 275 name = Fexpand_file_name (tem, dir);
07f4d123
RS
276 dir = Ffile_name_directory (name);
277 }
278 else
279 break;
280 }
281 }
282
f927c5ae
JB
283 Vcommand_line_args = Qnil;
284
285 for (i = argc - 1; i >= 0; i--)
286 {
287 if (i == 0 || i > skip_args)
288 Vcommand_line_args
289 = Fcons (build_string (argv[i]), Vcommand_line_args);
290 }
291}
59653951
JB
292
293DEFUN ("invocation-name", Finvocation_name, Sinvocation_name, 0, 0, 0,
294 "Return the program name that was used to run Emacs.\n\
295Any directory names are omitted.")
296 ()
297{
298 return Fcopy_sequence (Vinvocation_name);
299}
300
ace40a69
RS
301DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory,
302 0, 0, 0,
303 "Return the directory name in which the Emacs executable was located")
304 ()
305{
306 return Fcopy_sequence (Vinvocation_directory);
307}
308
f927c5ae
JB
309\f
310#ifdef VMS
311#ifdef LINK_CRTL_SHARE
312#ifdef SHAREABLE_LIB_BUG
313extern noshare char **environ;
314#endif /* SHAREABLE_LIB_BUG */
315#endif /* LINK_CRTL_SHARE */
316#endif /* VMS */
317
a90538cb 318#ifndef ORDINARY_LINK
efd241cc
RS
319/* We don't include crtbegin.o and crtend.o in the link,
320 so these functions and variables might be missed.
321 Provide dummy definitions to avoid error.
322 (We don't have any real constructors or destructors.) */
323#ifdef __GNUC__
46e65b73 324#ifndef GCC_CTORS_IN_LIBC
c83a7064 325__do_global_ctors ()
efd241cc 326{}
c83a7064
RS
327__do_global_ctors_aux ()
328{}
33143604
RS
329__do_global_dtors ()
330{}
64c1864a
RS
331/* Linux has a bug in its library; avoid an error. */
332#ifndef LINUX
c83a7064 333char * __CTOR_LIST__[2] = { (char *) (-1), 0 };
64c1864a 334#endif
c83a7064 335char * __DTOR_LIST__[2] = { (char *) (-1), 0 };
46e65b73 336#endif /* GCC_CTORS_IN_LIBC */
c83a7064 337__main ()
efd241cc 338{}
efd241cc 339#endif /* __GNUC__ */
a90538cb 340#endif /* ORDINARY_LINK */
efd241cc 341
e2925360
KH
342/* Test whether the next argument in ARGV matches SSTR or a prefix of
343 LSTR (at least MINLEN characters). If so, then if VALPTR is non-null
344 (the argument is supposed to have a value) store in *VALPTR either
345 the next argument or the portion of this one after the equal sign.
346 ARGV is read starting at position *SKIPPTR; this index is advanced
347 by the number of arguments used.
348
349 Too bad we can't just use getopt for all of this, but we don't have
350 enough information to do it right. */
081bef73 351
e2925360 352static int
df6530f8 353argmatch (argv, argc, sstr, lstr, minlen, valptr, skipptr)
e2925360 354 char **argv;
df6530f8 355 int argc;
e2925360
KH
356 char *sstr;
357 char *lstr;
358 int minlen;
359 char **valptr;
360 int *skipptr;
361{
362 char *p;
363 int arglen;
df6530f8
RS
364 char *arg;
365
366 /* Don't access argv[argc]; give up in advance. */
367 if (argc <= *skipptr + 1)
368 return 0;
369
370 arg = argv[*skipptr+1];
e2925360
KH
371 if (arg == NULL)
372 return 0;
373 if (strcmp (arg, sstr) == 0)
374 {
375 if (valptr != NULL)
376 {
377 *valptr = argv[*skipptr+2];
378 *skipptr += 2;
379 }
380 else
381 *skipptr += 1;
382 return 1;
383 }
384 arglen = (valptr != NULL && (p = index (arg, '=')) != NULL
385 ? p - arg : strlen (arg));
c03e1113 386 if (lstr == 0 || arglen < minlen || strncmp (arg, lstr, arglen) != 0)
e2925360
KH
387 return 0;
388 else if (valptr == NULL)
389 {
390 *skipptr += 1;
391 return 1;
392 }
393 else if (p != NULL)
394 {
395 *valptr = p+1;
396 *skipptr += 1;
397 return 1;
398 }
399 else if (argv[*skipptr+2] != NULL)
400 {
401 *valptr = argv[*skipptr+2];
402 *skipptr += 2;
403 return 1;
404 }
405 else
406 {
407 return 0;
408 }
409}
410
f927c5ae
JB
411/* ARGSUSED */
412main (argc, argv, envp)
413 int argc;
414 char **argv;
415 char **envp;
416{
417 char stack_bottom_variable;
418 int skip_args = 0;
419 extern int errno;
420 extern sys_nerr;
f927c5ae 421
6000fe37
RS
422#ifdef LINUX_SBRK_BUG
423 __sbrk (1);
424#endif
425
081bef73
RS
426 sort_args (argc, argv);
427
1702afef
RS
428 if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args))
429 {
430 Lisp_Object tem;
431 tem = Fsymbol_value (intern ("emacs-version"));
432 if (!STRINGP (tem))
433 {
434 fprintf (stderr, "Invalid value of `emacs-version'\n");
435 exit (1);
436 }
437 else
438 {
439 printf ("%s\n", XSTRING (tem)->data);
440 exit (0);
441 }
442 }
443
f927c5ae
JB
444/* Map in shared memory, if we are using that. */
445#ifdef HAVE_SHM
df6530f8 446 if (argmatch (argv, argc, "-nl", "--no-shared-memory", 6, NULL, &skip_args))
f927c5ae
JB
447 {
448 map_in_data (0);
449 /* The shared memory was just restored, which clobbered this. */
450 skip_args = 1;
451 }
452 else
453 {
454 map_in_data (1);
455 /* The shared memory was just restored, which clobbered this. */
456 skip_args = 0;
457 }
458#endif
459
19a36ec6 460#ifdef NeXT
b9df9faa
KH
461 {
462 extern int malloc_cookie;
463 /* This helps out unexnext.c. */
464 if (initialized)
465 if (malloc_jumpstart (malloc_cookie) != 0)
466 printf ("malloc jumpstart failed!\n");
467 }
19a36ec6
RS
468#endif /* NeXT */
469
f927c5ae
JB
470#ifdef VMS
471 /* If -map specified, map the data file in */
e2925360
KH
472 {
473 char *file;
df6530f8 474 if (argmatch (argv, argc, "-map", "--map-data", 3, &mapin_file, &skip_args))
e2925360
KH
475 mapin_data (file);
476 }
f927c5ae
JB
477
478#ifdef LINK_CRTL_SHARE
479#ifdef SHAREABLE_LIB_BUG
480 /* Bletcherous shared libraries! */
481 if (!stdin)
482 stdin = fdopen (0, "r");
483 if (!stdout)
484 stdout = fdopen (1, "w");
485 if (!stderr)
486 stderr = fdopen (2, "w");
487 if (!environ)
488 environ = envp;
489#endif /* SHAREABLE_LIB_BUG */
490#endif /* LINK_CRTL_SHARE */
491#endif /* VMS */
492
493 /* Record (approximately) where the stack begins. */
494 stack_bottom = &stack_bottom_variable;
495
496#ifdef RUN_TIME_REMAP
497 if (initialized)
498 run_time_remap (argv[0]);
499#endif
500
501#ifdef USG_SHARED_LIBRARIES
502 if (bss_end)
1d233b80 503 brk ((void *)bss_end);
f927c5ae
JB
504#endif
505
506 clearerr (stdin);
9ae8f997 507
f927c5ae
JB
508#ifndef SYSTEM_MALLOC
509 if (! initialized)
9ac0d9e0
JB
510 {
511 /* Arrange to get warning messages as memory fills up. */
512 memory_warnings (0, malloc_warning);
513
514 /* Arrange to disable interrupt input while malloc and friends are
515 running. */
516 uninterrupt_malloc ();
517 }
f927c5ae
JB
518#endif /* not SYSTEM_MALLOC */
519
29b89fe0
RS
520#ifdef MSDOS
521 /* We do all file input/output as binary files. When we need to translate
522 newlines, we do that manually. */
523 _fmode = O_BINARY;
524 (stdin)->_flag &= ~_IOTEXT;
525 (stdout)->_flag &= ~_IOTEXT;
526 (stderr)->_flag &= ~_IOTEXT;
527#endif /* MSDOS */
528
a422068f 529#ifdef SET_EMACS_PRIORITY
3005da00 530 if (emacs_priority)
5aa7f46a 531 nice (emacs_priority);
f927c5ae 532 setuid (getuid ());
a422068f 533#endif /* SET_EMACS_PRIORITY */
f927c5ae 534
d8b3a65d 535#ifdef EXTRA_INITIALIZE
a9260219 536 EXTRA_INITIALIZE;
d8b3a65d
RS
537#endif
538
f927c5ae
JB
539 inhibit_window_system = 0;
540
4fc0b45b 541 /* Handle the -t switch, which specifies filename to use as terminal */
e2925360
KH
542 {
543 char *term;
df6530f8 544 if (argmatch (argv, argc, "-t", "--terminal", 4, &term, &skip_args))
e2925360
KH
545 {
546 int result;
547 close (0);
548 close (1);
549 result = open (term, O_RDWR, 2 );
550 if (result < 0)
551 {
552 char *errstring = strerror (errno);
553 fprintf (stderr, "emacs: %s: %s\n", term, errstring);
554 exit (1);
555 }
556 dup (0);
557 if (! isatty (0))
558 {
559 fprintf (stderr, "emacs: %s: not a tty\n", term);
560 exit (1);
561 }
562 fprintf (stderr, "Using %s\n", term);
8ba50e1a 563#ifdef HAVE_WINDOW_SYSTEM
e2925360 564 inhibit_window_system = 1; /* -t => -nw */
f927c5ae 565#endif
e2925360
KH
566 }
567 }
df6530f8 568 if (argmatch (argv, argc, "-nw", "--no-windows", 6, NULL, &skip_args))
e2925360 569 inhibit_window_system = 1;
f927c5ae 570
e2925360 571 /* Handle the -batch switch, which means don't do interactive display. */
f927c5ae 572 noninteractive = 0;
df6530f8 573 if (argmatch (argv, argc, "-batch", "--batch", 5, NULL, &skip_args))
e2925360
KH
574 noninteractive = 1;
575
576 /* Handle the --help option, which gives a usage message.. */
df6530f8 577 if (argmatch (argv, argc, "-help", "--help", 3, NULL, &skip_args))
f927c5ae 578 {
e2925360
KH
579 printf ("\
580Usage: %s [-t term] [--terminal term] [-nw] [--no-windows] [--batch]\n\
581 [-q] [--no-init-file] [-u user] [--user user] [--debug-init]\n\
afaa660f 582 [--version] [--no-site-file]\n\
e2925360 583 [-f func] [--funcall func] [-l file] [--load file] [--insert file]\n\
afaa660f 584 [+linenum] file-to-visit [--kill]\n", argv[0]);
e2925360 585 exit (0);
f927c5ae
JB
586 }
587
081bef73
RS
588#ifdef HAVE_X_WINDOWS
589 /* Stupid kludge to catch command-line display spec. We can't
590 handle this argument entirely in window system dependent code
591 because we don't even know which window system dependent code
592 to run until we've recognized this argument. */
593 {
594 char *displayname;
595 int i;
596 int count_before = skip_args;
597
df6530f8 598 if (argmatch (argv, argc, "-d", "--display", 3, &displayname, &skip_args))
081bef73 599 display_arg = 1;
df6530f8 600 else if (argmatch (argv, argc, "-display", 0, 3, &displayname, &skip_args))
081bef73
RS
601 display_arg = 1;
602
603 /* If we have the form --display=NAME,
604 convert it into -d name.
605 This requires inserting a new element into argv. */
606 if (displayname != 0 && skip_args - count_before == 1)
607 {
608 char **new = (char **) xmalloc (sizeof (char *) * (argc + 2));
609 int j;
610
611 for (j = 0; j < count_before + 1; j++)
612 new[j] = argv[j];
613 new[count_before + 1] = "-d";
614 new[count_before + 2] = displayname;
615 for (j = count_before + 2; j <argc; j++)
616 new[j + 1] = argv[j];
617 argv = new;
618 argc++;
619 }
1702afef
RS
620 /* Change --display to -d, when its arg is separate. */
621 else if (displayname != 0 && skip_args > count_before
622 && argv[count_before + 1][1] == '-')
813f79d5 623 argv[count_before + 1] = "-d";
081bef73
RS
624
625 /* Don't actually discard this arg. */
626 skip_args = count_before;
627 }
628#endif
629
edb85f59
RS
630 if (! noninteractive)
631 {
632#ifdef BSD_PGRPS
633 if (initialized)
634 {
635 inherited_pgroup = EMACS_GETPGRP (0);
636 setpgrp (0, getpid ());
637 }
638#else
639#if defined (USG5) && defined (INTERRUPT_INPUT)
640 setpgrp ();
641#endif
642#endif
643 }
644
fb8e9847
JB
645#ifdef POSIX_SIGNALS
646 init_signals ();
647#endif
648
f927c5ae
JB
649 if (
650#ifndef CANNOT_DUMP
651 ! noninteractive || initialized
652#else
653 1
654#endif
655 )
656 {
657 /* Don't catch these signals in batch mode if not initialized.
658 On some machines, this sets static data that would make
659 signal fail to work right when the dumped Emacs is run. */
660 signal (SIGHUP, fatal_error_signal);
661 signal (SIGQUIT, fatal_error_signal);
662 signal (SIGILL, fatal_error_signal);
663 signal (SIGTRAP, fatal_error_signal);
99e372cd
RS
664#ifdef SIGABRT
665 signal (SIGABRT, fatal_error_signal);
666#endif
667#ifdef SIGHWE
668 signal (SIGHWE, fatal_error_signal);
669#endif
670#ifdef SIGPRE
671 signal (SIGPRE, fatal_error_signal);
672#endif
673#ifdef SIGORE
674 signal (SIGORE, fatal_error_signal);
675#endif
676#ifdef SIGUME
677 signal (SIGUME, fatal_error_signal);
678#endif
679#ifdef SIGDLK
680 signal (SIGDLK, fatal_error_signal);
681#endif
682#ifdef SIGCPULIM
683 signal (SIGCPULIM, fatal_error_signal);
684#endif
a90538cb
JB
685#ifdef SIGIOT
686 /* This is missing on some systems - OS/2, for example. */
f927c5ae 687 signal (SIGIOT, fatal_error_signal);
a90538cb 688#endif
f927c5ae
JB
689#ifdef SIGEMT
690 signal (SIGEMT, fatal_error_signal);
691#endif
692 signal (SIGFPE, fatal_error_signal);
00eaaa32 693#ifdef SIGBUS
f927c5ae 694 signal (SIGBUS, fatal_error_signal);
00eaaa32 695#endif
f927c5ae 696 signal (SIGSEGV, fatal_error_signal);
00eaaa32 697#ifdef SIGSYS
f927c5ae 698 signal (SIGSYS, fatal_error_signal);
00eaaa32 699#endif
f927c5ae
JB
700 signal (SIGTERM, fatal_error_signal);
701#ifdef SIGXCPU
702 signal (SIGXCPU, fatal_error_signal);
703#endif
704#ifdef SIGXFSZ
705 signal (SIGXFSZ, fatal_error_signal);
706#endif /* SIGXFSZ */
707
271c7b7c
RS
708#ifdef SIGDANGER
709 /* This just means available memory is getting low. */
710 signal (SIGDANGER, memory_warning_signal);
711#endif
712
f927c5ae 713#ifdef AIX
56e034fa
RS
714/* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */
715 signal (SIGXCPU, fatal_error_signal);
0aef8561 716#ifndef _I386
f927c5ae 717 signal (SIGIOINT, fatal_error_signal);
0aef8561 718#endif
f927c5ae
JB
719 signal (SIGGRANT, fatal_error_signal);
720 signal (SIGRETRACT, fatal_error_signal);
721 signal (SIGSOUND, fatal_error_signal);
722 signal (SIGMSG, fatal_error_signal);
723#endif /* AIX */
724 }
725
726 noninteractive1 = noninteractive;
727
728/* Perform basic initializations (not merely interning symbols) */
729
730 if (!initialized)
731 {
732 init_alloc_once ();
733 init_obarray ();
734 init_eval_once ();
735 init_syntax_once (); /* Create standard syntax table. */
736 /* Must be done before init_buffer */
737 init_casetab_once ();
738 init_buffer_once (); /* Create buffer table and some buffers */
739 init_minibuf_once (); /* Create list of minibuffers */
740 /* Must precede init_window_once */
741 init_window_once (); /* Init the window system */
742 }
743
744 init_alloc ();
f927c5ae
JB
745 init_eval ();
746 init_data ();
7074fde6 747 running_asynch_code = 0;
0e956009 748
29b89fe0
RS
749#ifdef MSDOS
750 /* Call early 'cause init_environment needs it. */
751 init_dosfns ();
752 /* Set defaults for several environment variables. */
753 if (initialized) init_environment (argc, argv, skip_args);
fc300075 754 else init_gettimeofday ();
29b89fe0
RS
755#endif
756
8ba50e1a
GV
757#ifdef WINDOWSNT
758 /* Initialize environment from registry settings. */
759 init_environment ();
760#endif
761
0e956009
JB
762 /* egetenv is a pretty low-level facility, which may get called in
763 many circumstances; it seems flimsy to put off initializing it
764 until calling init_callproc. */
765 set_process_environment ();
93aed04d
RS
766 /* AIX crashes are reported in system versions 3.2.3 and 3.2.4
767 if this is not done. Do it after set_process_environment so that we
768 don't pollute Vprocess_environment. */
769#ifdef AIX
770 putenv ("LANG=C");
771#endif
0e956009 772
ace40a69
RS
773 init_buffer (); /* Init default directory of main buffer */
774
7928f0b5 775 init_callproc_1 (); /* Must precede init_cmdargs and init_sys_modes. */
ace40a69 776 init_cmdargs (argc, argv, skip_args); /* Must precede init_lread. */
7928f0b5 777 init_callproc (); /* Must follow init_cmdargs but not init_sys_modes. */
fb8e9847 778 init_lread ();
f927c5ae 779
f927c5ae
JB
780 if (!noninteractive)
781 {
782#ifdef VMS
1cbd5d9d 783 init_vms_input ();/* init_display calls get_frame_size, that needs this */
f927c5ae
JB
784#endif /* VMS */
785 init_display (); /* Determine terminal type. init_sys_modes uses results */
786 }
787 init_keyboard (); /* This too must precede init_sys_modes */
f927c5ae
JB
788#ifdef VMS
789 init_vmsproc (); /* And this too. */
790#endif /* VMS */
791 init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.) */
792 init_xdisp ();
793 init_macros ();
794 init_editfns ();
795#ifdef LISP_FLOAT_TYPE
796 init_floatfns ();
797#endif
798#ifdef VMS
799 init_vmsfns ();
800#endif /* VMS */
f927c5ae 801 init_process ();
32676c08
JB
802#ifdef CLASH_DETECTION
803 init_filelock ();
804#endif /* CLASH_DETECTION */
f927c5ae
JB
805
806/* Intern the names of all standard functions and variables; define standard keys */
807
808 if (!initialized)
809 {
810 /* The basic levels of Lisp must come first */
811 /* And data must come first of all
812 for the sake of symbols like error-message */
813 syms_of_data ();
814 syms_of_alloc ();
fb8e9847 815 syms_of_lread ();
f927c5ae
JB
816 syms_of_print ();
817 syms_of_eval ();
818 syms_of_fns ();
f927c5ae 819 syms_of_floatfns ();
f927c5ae
JB
820
821 syms_of_abbrev ();
822 syms_of_buffer ();
823 syms_of_bytecode ();
824 syms_of_callint ();
825 syms_of_casefiddle ();
826 syms_of_casetab ();
827 syms_of_callproc ();
828 syms_of_cmds ();
829#ifndef NO_DIR_LIBRARY
830 syms_of_dired ();
831#endif /* not NO_DIR_LIBRARY */
832 syms_of_display ();
833 syms_of_doc ();
834 syms_of_editfns ();
835 syms_of_emacs ();
836 syms_of_fileio ();
837#ifdef CLASH_DETECTION
838 syms_of_filelock ();
839#endif /* CLASH_DETECTION */
840 syms_of_indent ();
841 syms_of_keyboard ();
842 syms_of_keymap ();
843 syms_of_macros ();
844 syms_of_marker ();
845 syms_of_minibuf ();
846 syms_of_mocklisp ();
f927c5ae 847 syms_of_process ();
f927c5ae 848 syms_of_search ();
1cbd5d9d 849 syms_of_frame ();
f927c5ae 850 syms_of_syntax ();
0d934e7b 851 syms_of_term ();
f927c5ae 852 syms_of_undo ();
bef79ee4
JA
853
854 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
855 syms_of_textprop ();
f927c5ae
JB
856#ifdef VMS
857 syms_of_vmsproc ();
858#endif /* VMS */
859 syms_of_window ();
860 syms_of_xdisp ();
861#ifdef HAVE_X_WINDOWS
72412588 862 syms_of_xterm ();
f927c5ae 863 syms_of_xfns ();
9c3f23b7 864 syms_of_xfaces ();
72412588
JB
865#ifdef HAVE_X11
866 syms_of_xselect ();
867#endif
f927c5ae
JB
868#endif /* HAVE_X_WINDOWS */
869
87485d6f
MW
870#if defined (MSDOS) && !defined (HAVE_X_WINDOWS)
871 syms_of_xfaces ();
87485d6f
MW
872#endif
873
6c850f3c
RS
874#ifdef HAVE_MENUS
875 syms_of_xmenu ();
876#endif /* HAVE_MENUS */
877
8ba50e1a
GV
878#ifdef HAVE_NTGUI
879 syms_of_win32term ();
880 syms_of_win32fns ();
881 syms_of_win32faces ();
882 syms_of_win32select ();
883 syms_of_win32menu ();
884#endif /* HAVE_NTGUI */
885
f927c5ae
JB
886#ifdef SYMS_SYSTEM
887 SYMS_SYSTEM;
888#endif
889
890#ifdef SYMS_MACHINE
891 SYMS_MACHINE;
892#endif
893
894 keys_of_casefiddle ();
895 keys_of_cmds ();
896 keys_of_buffer ();
897 keys_of_keyboard ();
898 keys_of_keymap ();
899 keys_of_macros ();
900 keys_of_minibuf ();
901 keys_of_window ();
5e67fbc2 902 keys_of_frame ();
f927c5ae
JB
903 }
904
905 if (!initialized)
906 {
e2925360 907 char *file;
f927c5ae 908 /* Handle -l loadup-and-dump, args passed by Makefile. */
df6530f8 909 if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args))
f927c5ae 910 Vtop_level = Fcons (intern ("load"),
e2925360 911 Fcons (build_string (file), Qnil));
f927c5ae
JB
912#ifdef CANNOT_DUMP
913 /* Unless next switch is -nl, load "loadup.el" first thing. */
df6530f8 914 if (!argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args))
f927c5ae
JB
915 Vtop_level = Fcons (intern ("load"),
916 Fcons (build_string ("loadup.el"), Qnil));
917#endif /* CANNOT_DUMP */
918 }
919
93572b43
KH
920 if (initialized)
921 {
922 /* Erase any pre-dump messages in the message log, to avoid confusion */
923 Lisp_Object old_log_max;
924 old_log_max = Vmessage_log_max;
925 XSETFASTINT (Vmessage_log_max, 0);
926 message_dolog ("", 0, 1);
927 Vmessage_log_max = old_log_max;
928 }
929
f927c5ae
JB
930 initialized = 1;
931
e7536cff
RS
932#ifdef LOCALTIME_CACHE
933 /* Some versions of localtime have a bug. They cache the value of the time
279cc2b8
JB
934 zone rather than looking it up every time. Since localtime() is
935 called to bolt the undumping time into the undumped emacs, this
afe9fae9
RS
936 results in localtime ignoring the TZ environment variable.
937 This flushes the new TZ value into localtime. */
938 tzset ();
e7536cff 939#endif /* defined (LOCALTIME_CACHE) */
279cc2b8 940
f927c5ae
JB
941 /* Enter editor command loop. This never returns. */
942 Frecursive_edit ();
943 /* NOTREACHED */
944}
945\f
081bef73
RS
946/* Sort the args so we can find the most important ones
947 at the beginning of argv. */
948
949/* First, here's a table of all the standard options. */
950
951struct standard_args
952{
953 char *name;
954 char *longname;
955 int priority;
956 int nargs;
957};
958
959struct standard_args standard_args[] =
960{
221cbd7d
RS
961 { "-version", "--version", 110, 0 },
962 { "-help", "--help", 110, 0 },
081bef73 963 { "-nl", "--no-shared-memory", 100, 0 },
2725719a 964#ifdef VMS
081bef73 965 { "-map", "--map-data", 100, 0 },
2725719a 966#endif
081bef73
RS
967 { "-t", "--terminal", 90, 1 },
968 { "-d", "--display", 80, 1 },
969 { "-display", 0, 80, 1 },
970 { "-nw", "--no-windows", 70, 0 },
971 { "-batch", "--batch", 60, 0 },
972 { "-q", "--no-init-file", 50, 0 },
973 { "-no-init-file", 0, 50, 0 },
974 { "-no-site-file", "--no-site-file", 40, 0 },
975 { "-u", "--user", 30, 1 },
976 { "-user", 0, 30, 1 },
977 { "-debug-init", "--debug-init", 20, 0 },
adab4483
KH
978 { "-i", "--icon-type", 15, 0 },
979 { "-itype", 0, 15, 0 },
f2bc3538 980 { "-iconic", "--iconic", 15, 0 },
081bef73
RS
981 { "-bg", "--background-color", 10, 1 },
982 { "-background", 0, 10, 1 },
983 { "-fg", "--foreground-color", 10, 1 },
984 { "-foreground", 0, 10, 1 },
985 { "-bd", "--border-color", 10, 1 },
986 { "-bw", "--border-width", 10, 1 },
987 { "-ib", "--internal-border", 10, 1 },
988 { "-ms", "--mouse-color", 10, 1 },
989 { "-cr", "--cursor-color", 10, 1 },
990 { "-fn", "--font", 10, 1 },
991 { "-font", 0, 10, 1 },
992 { "-g", "--geometry", 10, 1 },
993 { "-geometry", 0, 10, 1 },
994 { "-T", "--title", 10, 1 },
081bef73
RS
995 { "-name", "--name", 10, 1 },
996 { "-xrm", "--xrm", 10, 1 },
fcdeb5d9
RS
997 { "-r", "--reverse-video", 5, 0 },
998 { "-rv", 0, 5, 0 },
999 { "-reverse", 0, 5, 0 },
1000 { "-vb", "--vertical-scroll-bars", 5, 0 },
fcdeb5d9
RS
1001 /* These have the same priority as ordinary file name args,
1002 so they are not reordered with respect to those. */
4af9e0b3
RS
1003 { "-L", "--directory", 0, 1 },
1004 { "-directory", 0, 0, 1 },
fcdeb5d9
RS
1005 { "-l", "--load", 0, 1 },
1006 { "-load", 0, 0, 1 },
1007 { "-f", "--funcall", 0, 1 },
1008 { "-funcall", 0, 0, 1 },
575985b1 1009 { "-eval", "--eval", 0, 1 },
fcdeb5d9 1010 { "-insert", "--insert", 0, 1 },
f2bc3538 1011 /* This should be processed after ordinary file name args and the like. */
fcdeb5d9 1012 { "-kill", "--kill", -10, 0 },
081bef73
RS
1013};
1014
1015/* Reorder the elements of ARGV (assumed to have ARGC elements)
1016 so that the highest priority ones come first.
1017 Do not change the order of elements of equal priority.
1018 If an option takes an argument, keep it and its argument together. */
1019
1020static void
1021sort_args (argc, argv)
1022 int argc;
1023 char **argv;
1024{
1025 char **new = (char **) xmalloc (sizeof (char *) * argc);
1026 /* For each element of argv,
1027 the corresponding element of options is:
1028 0 for an option that takes no arguments,
1029 1 for an option that takes one argument, etc.
1030 -1 for an ordinary non-option argument. */
6dad9359 1031 int *options = (int *) xmalloc (sizeof (int) * argc);
081bef73
RS
1032 int *priority = (int *) xmalloc (sizeof (int) * argc);
1033 int to = 1;
1034 int from;
1035 int i;
1036
1037 /* Categorize all the options,
1038 and figure out which argv elts are option arguments. */
1039 for (from = 1; from < argc; from++)
1040 {
1041 options[from] = -1;
fcdeb5d9 1042 priority[from] = 0;
081bef73
RS
1043 if (argv[from][0] == '-')
1044 {
1045 int match, thislen;
1046 char *equals;
1047
1048 /* Look for a match with a known old-fashioned option. */
1049 for (i = 0; i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
1050 if (!strcmp (argv[from], standard_args[i].name))
1051 {
1052 options[from] = standard_args[i].nargs;
1053 priority[from] = standard_args[i].priority;
1054 from += standard_args[i].nargs;
1055 goto done;
1056 }
1057
1058 /* Look for a match with a known long option.
1059 MATCH is -1 if no match so far, -2 if two or more matches so far,
1060 >= 0 (the table index of the match) if just one match so far. */
1061 if (argv[from][1] == '-')
1062 {
1063 match = -1;
1064 thislen = strlen (argv[from]);
1065 equals = index (argv[from], '=');
1066 if (equals != 0)
1067 thislen = equals - argv[from];
1068
f609ef57
KH
1069 for (i = 0;
1070 i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
1071 if (standard_args[i].longname
1072 && !strncmp (argv[from], standard_args[i].longname,
1073 thislen))
081bef73
RS
1074 {
1075 if (match == -1)
1076 match = i;
1077 else
1078 match = -2;
1079 }
1080
1081 /* If we found exactly one match, use that. */
1082 if (match >= 0)
1083 {
1084 options[from] = standard_args[match].nargs;
1085 priority[from] = standard_args[match].priority;
1086 /* If --OPTION=VALUE syntax is used,
1087 this option uses just one argv element. */
1088 if (equals != 0)
1089 options[from] = 0;
1090 from += options[from];
1091 }
1092 }
1093 done: ;
1094 }
1095 }
1096
1097 /* Copy the arguments, in order of decreasing priority, to NEW. */
1098 new[0] = argv[0];
1099 while (to < argc)
1100 {
1101 int best = -1;
2c70c992 1102 int best_priority = -9999;
081bef73
RS
1103
1104 /* Find the highest priority remaining option.
1105 If several have equal priority, take the first of them. */
1106 for (from = 1; from < argc; from++)
1107 {
1108 if (argv[from] != 0 && priority[from] > best_priority)
1109 {
1110 best_priority = priority[from];
1111 best = from;
1112 }
1113 /* Skip option arguments--they are tied to the options. */
1114 if (options[from] > 0)
1115 from += options[from];
1116 }
1117
1118 if (best < 0)
1119 abort ();
1120
1121 /* Copy the highest priority remaining option, with its args, to NEW. */
1122 new[to++] = argv[best];
1123 for (i = 0; i < options[best]; i++)
1124 new[to++] = argv[best + i + 1];
1125
1126 /* Clear out this option in ARGV. */
1127 argv[best] = 0;
1128 for (i = 0; i < options[best]; i++)
1129 argv[best + i + 1] = 0;
1130 }
1131
6dad9359 1132 bcopy (new, argv, sizeof (char *) * argc);
081bef73
RS
1133}
1134\f
f927c5ae 1135DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P",
edc8ae07 1136 "Exit the Emacs job and kill it.\n\
f927c5ae
JB
1137If ARG is an integer, return ARG as the exit program code.\n\
1138If ARG is a string, stuff it as keyboard input.\n\n\
1139The value of `kill-emacs-hook', if not void,\n\
1140is a list of functions (of no args),\n\
1141all of which are called before Emacs is actually killed.")
1142 (arg)
1143 Lisp_Object arg;
1144{
1145 Lisp_Object hook, hook1;
1146 int i;
1147 struct gcpro gcpro1;
1148
1149 GCPRO1 (arg);
1150
1151 if (feof (stdin))
1152 arg = Qt;
1153
2447c626 1154 if (!NILP (Vrun_hooks) && !noninteractive)
f927c5ae
JB
1155 call1 (Vrun_hooks, intern ("kill-emacs-hook"));
1156
f927c5ae
JB
1157 UNGCPRO;
1158
1159/* Is it really necessary to do this deassign
1160 when we are going to exit anyway? */
1161/* #ifdef VMS
1162 stop_vms_input ();
1163 #endif */
40be253a 1164
d0068e25 1165 shut_down_emacs (0, 0, STRINGP (arg) ? arg : Qnil);
40be253a 1166
58545838
KH
1167 /* If we have an auto-save list file,
1168 kill it because we are exiting Emacs deliberately (not crashing).
1169 Do it after shut_down_emacs, which does an auto-save. */
1170 if (STRINGP (Vauto_save_list_file_name))
1171 unlink (XSTRING (Vauto_save_list_file_name)->data);
1172
55ccc0b3 1173 exit (INTEGERP (arg) ? XINT (arg)
f927c5ae
JB
1174#ifdef VMS
1175 : 1
1176#else
1177 : 0
1178#endif
1179 );
1180 /* NOTREACHED */
1181}
40be253a
JB
1182
1183
1184/* Perform an orderly shutdown of Emacs. Autosave any modified
1185 buffers, kill any child processes, clean up the terminal modes (if
1186 we're in the foreground), and other stuff like that. Don't perform
1187 any redisplay; this may be called when Emacs is shutting down in
1188 the background, or after its X connection has died.
1189
1190 If SIG is a signal number, print a message for it.
1191
1192 This is called by fatal signal handlers, X protocol error handlers,
1193 and Fkill_emacs. */
f7ab4e3d 1194
40be253a 1195void
f7ab4e3d 1196shut_down_emacs (sig, no_x, stuff)
41423a80 1197 int sig, no_x;
f7ab4e3d 1198 Lisp_Object stuff;
40be253a 1199{
829d872b
RS
1200 /* Prevent running of hooks from now on. */
1201 Vrun_hooks = Qnil;
1202
40be253a
JB
1203 /* If we are controlling the terminal, reset terminal modes */
1204#ifdef EMACS_HAVE_TTY_PGRP
1205 {
d04d81d2
RS
1206 int pgrp = EMACS_GETPGRP (0);
1207
40be253a
JB
1208 int tpgrp;
1209 if (EMACS_GET_TTY_PGRP (0, &tpgrp) != -1
5a570e37 1210 && tpgrp == pgrp)
40be253a
JB
1211 {
1212 fflush (stdout);
1213 reset_sys_modes ();
1214 if (sig && sig != SIGTERM)
1215 fprintf (stderr, "Fatal error (%d).", sig);
1216 }
1217 }
1218#else
1219 fflush (stdout);
1220 reset_sys_modes ();
1221#endif
1222
f7ab4e3d
RS
1223 stuff_buffered_input (stuff);
1224
40be253a
JB
1225 kill_buffer_processes (Qnil);
1226 Fdo_auto_save (Qt, Qnil);
1227
1228#ifdef CLASH_DETECTION
1229 unlock_all_files ();
1230#endif
1231
1232#ifdef VMS
1233 kill_vms_processes ();
1234#endif
1235
5e7f8733 1236#if 0 /* This triggers a bug in XCloseDisplay and is not needed. */
41423a80 1237#ifdef HAVE_X_WINDOWS
f7511647
RS
1238 /* It's not safe to call intern here. Maybe we are crashing. */
1239 if (!noninteractive && SYMBOLP (Vwindow_system)
1240 && XSYMBOL (Vwindow_system)->name->size == 1
1241 && XSYMBOL (Vwindow_system)->name->data[0] == 'x'
1242 && ! no_x)
41423a80
RS
1243 Fx_close_current_connection ();
1244#endif /* HAVE_X_WINDOWS */
5e7f8733 1245#endif
41423a80 1246
40be253a
JB
1247#ifdef SIGIO
1248 /* There is a tendency for a SIGIO signal to arrive within exit,
1249 and cause a SIGHUP because the input descriptor is already closed. */
1250 unrequest_sigio ();
1251 signal (SIGIO, SIG_IGN);
1252#endif
1253}
1254
1255
f927c5ae
JB
1256\f
1257#ifndef CANNOT_DUMP
f927c5ae
JB
1258
1259#ifdef HAVE_SHM
1260
1261DEFUN ("dump-emacs-data", Fdump_emacs_data, Sdump_emacs_data, 1, 1, 0,
1262 "Dump current state of Emacs into data file FILENAME.\n\
1263This function exists on systems that use HAVE_SHM.")
1264 (intoname)
1265 Lisp_Object intoname;
1266{
55697f5b 1267 extern char my_edata[];
f927c5ae 1268 Lisp_Object tem;
f927c5ae
JB
1269
1270 CHECK_STRING (intoname, 0);
1271 intoname = Fexpand_file_name (intoname, Qnil);
1272
1273 tem = Vpurify_flag;
1274 Vpurify_flag = Qnil;
1275
1276 fflush (stdout);
1277 /* Tell malloc where start of impure now is */
1278 /* Also arrange for warnings when nearly out of space. */
1279#ifndef SYSTEM_MALLOC
1090a161 1280 memory_warnings (my_edata, malloc_warning);
f927c5ae
JB
1281#endif
1282 map_out_data (XSTRING (intoname)->data);
1283
1284 Vpurify_flag = tem;
1285
1286 return Qnil;
1287}
1288
1289#else /* not HAVE_SHM */
1290
1291DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0,
1292 "Dump current state of Emacs into executable file FILENAME.\n\
1293Take symbols from SYMFILE (presumably the file you executed to run Emacs).\n\
1294This is used in the file `loadup.el' when building Emacs.\n\
1295\n\
1296Bind `command-line-processed' to nil before dumping,\n\
1297if you want the dumped Emacs to process its command line\n\
1298and announce itself normally when it is run.")
1299 (intoname, symname)
1300 Lisp_Object intoname, symname;
1301{
55697f5b 1302 extern char my_edata[];
f927c5ae 1303 Lisp_Object tem;
f927c5ae
JB
1304
1305 CHECK_STRING (intoname, 0);
1306 intoname = Fexpand_file_name (intoname, Qnil);
2447c626 1307 if (!NILP (symname))
f927c5ae
JB
1308 {
1309 CHECK_STRING (symname, 0);
1310 if (XSTRING (symname)->size)
1311 symname = Fexpand_file_name (symname, Qnil);
1312 }
1313
1314 tem = Vpurify_flag;
1315 Vpurify_flag = Qnil;
1316
1317 fflush (stdout);
1318#ifdef VMS
1319 mapout_data (XSTRING (intoname)->data);
1320#else
1321 /* Tell malloc where start of impure now is */
1322 /* Also arrange for warnings when nearly out of space. */
1323#ifndef SYSTEM_MALLOC
cc5f52cb
RS
1324#ifndef WINDOWSNT
1325 /* On Windows, this was done before dumping, and that once suffices.
1326 Meanwhile, my_edata is not valid on Windows. */
cb37cf78 1327 memory_warnings (my_edata, malloc_warning);
cc5f52cb 1328#endif /* not WINDOWSNT */
f927c5ae
JB
1329#endif
1330 unexec (XSTRING (intoname)->data,
c91e1ad0 1331 !NILP (symname) ? XSTRING (symname)->data : 0, my_edata, 0, 0);
f927c5ae
JB
1332#endif /* not VMS */
1333
1334 Vpurify_flag = tem;
1335
1336 return Qnil;
1337}
1338
1339#endif /* not HAVE_SHM */
1340
1341#endif /* not CANNOT_DUMP */
1342\f
4b163808 1343#ifndef SEPCHAR
f927c5ae
JB
1344#define SEPCHAR ':'
1345#endif
1346
1347Lisp_Object
1348decode_env_path (evarname, defalt)
1349 char *evarname, *defalt;
1350{
1351 register char *path, *p;
f927c5ae
JB
1352
1353 Lisp_Object lpath;
1354
2447c626
JB
1355 /* It's okay to use getenv here, because this function is only used
1356 to initialize variables when Emacs starts up, and isn't called
1357 after that. */
e065a56e
JB
1358 if (evarname != 0)
1359 path = (char *) getenv (evarname);
1360 else
1361 path = 0;
f927c5ae
JB
1362 if (!path)
1363 path = defalt;
1364 lpath = Qnil;
1365 while (1)
1366 {
1367 p = index (path, SEPCHAR);
1368 if (!p) p = path + strlen (path);
d70fbcca
RS
1369 lpath = Fcons (p - path ? make_string (path, p - path)
1370 : build_string ("."),
f927c5ae
JB
1371 lpath);
1372 if (*p)
1373 path = p + 1;
1374 else
1375 break;
1376 }
1377 return Fnreverse (lpath);
1378}
1379
1380syms_of_emacs ()
1381{
83591e66 1382#ifndef CANNOT_DUMP
f927c5ae
JB
1383#ifdef HAVE_SHM
1384 defsubr (&Sdump_emacs_data);
1385#else
1386 defsubr (&Sdump_emacs);
83591e66 1387#endif
f927c5ae
JB
1388#endif
1389
1390 defsubr (&Skill_emacs);
1391
59653951 1392 defsubr (&Sinvocation_name);
ace40a69 1393 defsubr (&Sinvocation_directory);
59653951 1394
f927c5ae
JB
1395 DEFVAR_LISP ("command-line-args", &Vcommand_line_args,
1396 "Args passed by shell to Emacs, as a list of strings.");
1397
1398 DEFVAR_LISP ("system-type", &Vsystem_type,
1399 "Value is symbol indicating type of operating system you are using.");
1400 Vsystem_type = intern (SYSTEM_TYPE);
1401
271c7b7c
RS
1402 DEFVAR_LISP ("system-configuration", &Vsystem_configuration,
1403 "Value is string indicating configuration Emacs was built for.");
f7511647 1404 Vsystem_configuration = build_string (EMACS_CONFIGURATION);
271c7b7c 1405
f0fc0b1a
KH
1406 DEFVAR_LISP ("system-configuration-options", &Vsystem_configuration_options,
1407 "String containing the configuration options Emacs was built with.");
1408 Vsystem_configuration_options = build_string (EMACS_CONFIG_OPTIONS);
1409
f927c5ae
JB
1410 DEFVAR_BOOL ("noninteractive", &noninteractive1,
1411 "Non-nil means Emacs is running without interactive terminal.");
e5d77022 1412
e5d77022 1413 DEFVAR_LISP ("kill-emacs-hook", &Vkill_emacs_hook,
edc8ae07
JB
1414 "Hook to be run whenever kill-emacs is called.\n\
1415Since kill-emacs may be invoked when the terminal is disconnected (or\n\
1416in other similar situations), functions placed on this hook should not\n\
9f232a5d
RS
1417expect to be able to interact with the user. To ask for confirmation,\n\
1418see `kill-emacs-query-functions' instead.");
edc8ae07 1419 Vkill_emacs_hook = Qnil;
3005da00
RS
1420
1421 DEFVAR_INT ("emacs-priority", &emacs_priority,
1422 "Priority for Emacs to run at.\n\
1423This value is effective only if set before Emacs is dumped,\n\
1424and only if the Emacs executable is installed with setuid to permit\n\
621ecf99 1425it to change priority. (Emacs sets its uid back to the real uid.)\n\
a422068f 1426Currently, you need to define SET_EMACS_PRIORITY in `config.h'\n\
ce305b11 1427before you compile Emacs, to enable the code for this feature.");
3005da00 1428 emacs_priority = 0;
59653951 1429
f67de86f
RS
1430 DEFVAR_LISP ("invocation-name", &Vinvocation_name,
1431 "The program name that was used to run Emacs.\n\
1432Any directory names are omitted.");
1433
1434 DEFVAR_LISP ("invocation-directory", &Vinvocation_directory,
1435 "The directory in which the Emacs executable was found, to run it.\n\
1436The value is nil if that directory's name is not known.");
1437
1438 DEFVAR_LISP ("installation-directory", &Vinstallation_directory,
1439 "A directory within which to look for the `lib-src' and `etc' directories.\n\
1440This is non-nil when we can't find those directories in their standard\n\
1441installed locations, but we can find them\n\
1442near where the Emacs executable was found.");
07f4d123 1443 Vinstallation_directory = Qnil;
f927c5ae 1444}