Use the term `invalid' instead of `illegal'.
[bpt/emacs.git] / src / emacs.c
CommitLineData
f927c5ae 1/* Fully extensible Emacs, running on Unix, intended for GNU.
68c45bf0 2 Copyright (C) 1985,86,87,93,94,95,97,98,1999 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
5a7670bf
RS
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
f927c5ae
JB
20
21
68c45bf0 22#include <config.h>
f927c5ae
JB
23#include <signal.h>
24#include <errno.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
cda4a5fd
GM
34#ifdef HAVE_UNISTD_H
35#include <unistd.h>
36#endif
37
488b7cb3 38#ifdef BSD_SYSTEM
f927c5ae
JB
39#include <sys/ioctl.h>
40#endif
41
f927c5ae
JB
42#include "lisp.h"
43#include "commands.h"
bef79ee4 44#include "intervals.h"
a08a816a 45#include "buffer.h"
f927c5ae 46
edc8ae07 47#include "systty.h"
6c3a4e9d 48#include "blockinput.h"
8090eb09 49#include "syssignal.h"
6c362a8b 50#include "process.h"
5bda49c6 51#include "termhooks.h"
dfcf069d 52#include "keyboard.h"
a41f8bed 53
68c45bf0
PE
54#ifdef HAVE_SETLOCALE
55#include <locale.h>
56#endif
57
53c58b5d
RS
58#ifdef HAVE_SETRLIMIT
59#include <sys/time.h>
60#include <sys/resource.h>
61#endif
62
f927c5ae
JB
63#ifndef O_RDWR
64#define O_RDWR 2
65#endif
66
43165242 67extern void malloc_warning ();
0269dedb 68extern void set_time_zone_rule ();
43165242 69extern char *index ();
43165242 70
30aa3f19
GM
71/* Make these values available in GDB, which doesn't see macros. */
72
73EMACS_INT gdb_valbits = VALBITS;
74EMACS_INT gdb_gctypebits = GCTYPEBITS;
75EMACS_INT gdb_emacs_intbits = sizeof (EMACS_INT) * BITS_PER_CHAR;
76#ifdef DATA_SEG_BITS
77EMACS_INT gdb_data_seg_bits = DATA_SEG_BITS;
78#else
79EMACS_INT gdb_data_seg_bits = 0;
80#endif
00da0e4a 81EMACS_INT PVEC_FLAG = PSEUDOVECTOR_FLAG;
30aa3f19 82
f927c5ae
JB
83/* Command line args from shell, as list of strings */
84Lisp_Object Vcommand_line_args;
85
59653951
JB
86/* The name under which Emacs was invoked, with any leading directory
87 names discarded. */
88Lisp_Object Vinvocation_name;
89
ace40a69
RS
90/* The directory name from which Emacs was invoked. */
91Lisp_Object Vinvocation_directory;
92
07f4d123
RS
93/* The directory name in which to find subdirs such as lisp and etc.
94 nil means get them only from PATH_LOADSEARCH. */
95Lisp_Object Vinstallation_directory;
96
e5d77022
JB
97/* Hook run by `kill-emacs' before it does really anything. */
98Lisp_Object Vkill_emacs_hook;
99
7317d9e8
RS
100#ifdef SIGUSR1
101/* Hooks for signal USR1 and USR2 handing */
102Lisp_Object Vsignal_USR1_hook;
103#ifdef SIGUSR2
104Lisp_Object Vsignal_USR2_hook;
105#endif
106#endif
107
074a066b
GV
108/* Search path separator. */
109Lisp_Object Vpath_separator;
110
f927c5ae
JB
111/* Set nonzero after Emacs has started up the first time.
112 Prevents reinitialization of the Lisp world and keymaps
113 on subsequent starts. */
114int initialized;
115
15aaf1b5
RS
116#ifdef DOUG_LEA_MALLOC
117/* Preserves a pointer to the memory allocated that copies that
118 static data inside glibc's malloc. */
119void *malloc_state_ptr;
120/* From glibc, a routine that returns a copy of the malloc internal state. */
121extern void *malloc_get_state ();
122/* From glibc, a routine that overwrites the malloc internal state. */
123extern void malloc_set_state ();
7c9cd446
AS
124/* Non-zero if the MALLOC_CHECK_ enviroment variable was set while
125 dumping. Used to work around a bug in glibc's malloc. */
126int malloc_using_checking;
15aaf1b5
RS
127#endif
128
271c7b7c 129/* Variable whose value is symbol giving operating system type. */
f927c5ae 130Lisp_Object Vsystem_type;
271c7b7c
RS
131
132/* Variable whose value is string giving configuration built for. */
133Lisp_Object Vsystem_configuration;
f0fc0b1a
KH
134
135/* Variable whose value is string giving configuration options,
136 for use when reporting bugs. */
137Lisp_Object Vsystem_configuration_options;
138
213d0b1f
RS
139Lisp_Object Qfile_name_handler_alist;
140
68c45bf0 141/* Current and previous system locales for messages and time. */
ca9c0567
PE
142Lisp_Object Vsystem_messages_locale;
143Lisp_Object Vprevious_system_messages_locale;
144Lisp_Object Vsystem_time_locale;
145Lisp_Object Vprevious_system_time_locale;
68c45bf0 146
f927c5ae
JB
147/* If non-zero, emacs should not attempt to use an window-specific code,
148 but instead should use the virtual terminal under which it was started */
149int inhibit_window_system;
150
5aa7f46a
JB
151/* If nonzero, set Emacs to run at this priority. This is also used
152 in child_setup and sys_suspend to make sure subshells run at normal
153 priority; Those functions have their own extern declaration. */
3005da00
RS
154int emacs_priority;
155
7074fde6
FP
156/* If non-zero a filter or a sentinel is running. Tested to save the match
157 data on the first attempt to change it inside asynchronous code. */
158int running_asynch_code;
159
647cec74 160#ifdef BSD_PGRPS
9ae8f997
JB
161/* See sysdep.c. */
162extern int inherited_pgroup;
163#endif
164
f927c5ae
JB
165#ifdef HAVE_X_WINDOWS
166/* If non-zero, -d was specified, meaning we're using some window system. */
167int display_arg;
168#endif
169
170/* An address near the bottom of the stack.
171 Tells GC how to save a copy of the stack. */
172char *stack_bottom;
173
8ba50e1a 174#ifdef HAVE_WINDOW_SYSTEM
f927c5ae 175extern Lisp_Object Vwindow_system;
8ba50e1a 176#endif /* HAVE_WINDOW_SYSTEM */
f927c5ae 177
1090a161
RS
178extern Lisp_Object Vauto_save_list_file_name;
179
f927c5ae
JB
180#ifdef USG_SHARED_LIBRARIES
181/* If nonzero, this is the place to put the end of the writable segment
182 at startup. */
183
184unsigned int bss_end = 0;
185#endif
186
187/* Nonzero means running Emacs without interactive terminal. */
188
189int noninteractive;
190
191/* Value of Lisp variable `noninteractive'.
192 Normally same as C variable `noninteractive'
193 but nothing terrible happens if user sets this one. */
194
195int noninteractive1;
e29f86e4
RS
196
197/* Save argv and argc. */
198char **initial_argv;
199int initial_argc;
081bef73
RS
200
201static void sort_args ();
dfcf069d 202void syms_of_emacs ();
bd4590ba 203
73ebcd25 204#define USAGE1 "\
bd4590ba
GM
205Usage: %s [OPTION-OR-FILENAME]...\n\
206\n\
207Run Emacs, the extensible, customizable, self-documenting real-time\n\
208display editor. The recommended way to start Emacs for normal editing\n\
209is with no options at all.\n\
210\n\
211Run M-x info RET m emacs RET m command arguments RET inside Emacs to\n\
212read the main documentation for these command-line arguments.\n\
213\n\
214Initialization options:\n\
215\n\
216--batch do not do interactive display; implies -q\n\
217--debug-init enable Emacs Lisp debugger during init file\n\
218--help display this help message and exit\n\
219--multibyte, --no-unibyte run Emacs in multibyte mode\n\
220--no-init-file, -q load neither ~/.emacs nor default.el\n\
221--no-shared-memory, -nl do not use shared memory\n\
222--no-site-file do not load site-start.el\n\
223--no-windows, -nw don't communicate with X, ignoring $DISPLAY\n\
224--terminal, -t DEVICE use DEVICE for terminal I/O\n\
225--unibyte, --no-multibyte run Emacs in unibyte mode\n\
226--user, -u USER load ~USER/.emacs instead of your own\n\
227--version display version information and exit\n\
228\n\
229Action options:\n\
230\n\
231FILE visit FILE using find-file\n\
232+LINENUM FILE visit FILE using find-file, then go to line LINENUM\n\
233--directory, -L DIR add DIR to variable load-path\n\
234--eval EXPR evaluate Emacs Lisp expression EXPR\n\
235--execute EXPR evaluate Emacs Lisp expression EXPR\n\
236--find-file FILE visit FILE\n\
237--funcall, -f FUNC call Emacs function FUNC with no arguments\n\
238--insert FILE insert contents of FILE into current buffer\n\
239--kill exit without asking for confirmation\n\
240--load, -l FILE load FILE of Emacs Lisp code using the load function\n\
241--visit FILE visit FILE\n\
73ebcd25
AI
242\n"
243
244#define USAGE2 "\
5b2ca26b 245Display options:\n\
bd4590ba
GM
246\n\
247--background-color, -bg COLOR window background color\n\
248--border-color, -bd COLOR main border color\n\
249--border-width, -bw WIDTH width of main border\n\
250--cursor-color, -cr COLOR color of the Emacs cursor indicating point\n\
251--display, -d DISPLAY use X server DISPLAY\n\
252--font, -fn FONT default font; must be fixed-widthp\n\
253--foreground-color, -fg COLOR window foreground color\n\
254--geometry, -g GEOMETRY window geometry\n\
255--iconic start Emacs in iconified state\n\
256--icon-type, -i use picture of gnu for Emacs icon\n\
257--internal-border, -ib WIDTH width between text and main border\n\
ecb5709c 258--line-spacing, -lsp PIXELS additional space to put between lines\n\
bd4590ba
GM
259--mouse-color, -ms COLOR mouse cursor color in Emacs window\n\
260--name NAME title of main Emacs window\n\
261--reverse-video, -r, -rv switch foreground and background\n\
262--title, -T, -wn, TITLE title for Emacs windows\n\
263--vertical-scroll-bars, -vb enable vertical scroll bars\n\
264--xrm XRESOURCES set additional X resources\n\
265\n\
266You can generally also specify long option names with a single -; for\n\
267example, -batch as well as --batch. You can use any unambiguous\n\
268abbreviation for a --option.\n\
269\n\
270Various environment variables and window system resources also affect\n\
271Emacs' operation. See the main documentation.\n\
272\n\
273Report bugs to bug-gnu-emacs@gnu.org. First, please see the Bugs\n\
274section of the Emacs manual or the file BUGS.\n"
275
f927c5ae
JB
276\f
277/* Signal code for the fatal signal that was received */
278int fatal_error_code;
279
280/* Nonzero if handling a fatal error already */
281int fatal_error_in_progress;
282
7317d9e8 283#ifdef SIGUSR1
7317d9e8
RS
284SIGTYPE
285handle_USR1_signal (sig)
286 int sig;
287{
5bda49c6
RS
288 struct input_event buf;
289
e2fa15ff
AS
290 buf.kind = user_signal;
291 buf.code = 0;
74c2d1c6 292 buf.frame_or_window = selected_frame;
5bda49c6
RS
293 buf.modifiers = 0;
294 buf.timestamp = 0;
295
296 kbd_buffer_store_event (&buf);
7317d9e8 297}
5bda49c6 298#endif /* SIGUSR1 */
fcf01ad3 299
7317d9e8 300#ifdef SIGUSR2
7317d9e8
RS
301SIGTYPE
302handle_USR2_signal (sig)
303 int sig;
304{
5bda49c6
RS
305 struct input_event buf;
306
e2fa15ff
AS
307 buf.kind = user_signal;
308 buf.code = 1;
74c2d1c6 309 buf.frame_or_window = selected_frame;
5bda49c6
RS
310 buf.modifiers = 0;
311 buf.timestamp = 0;
312
313 kbd_buffer_store_event (&buf);
7317d9e8 314}
5bda49c6 315#endif /* SIGUSR2 */
7317d9e8 316
9ab8560d 317/* Handle bus errors, invalid instruction, etc. */
2447c626 318SIGTYPE
f927c5ae
JB
319fatal_error_signal (sig)
320 int sig;
321{
f927c5ae
JB
322 fatal_error_code = sig;
323 signal (sig, SIG_DFL);
324
061b7f94
RS
325 TOTALLY_UNBLOCK_INPUT;
326
f927c5ae 327 /* If fatal error occurs in code below, avoid infinite recursion. */
8090eb09
JB
328 if (! fatal_error_in_progress)
329 {
330 fatal_error_in_progress = 1;
f927c5ae 331
f7ab4e3d 332 shut_down_emacs (sig, 0, Qnil);
8090eb09 333 }
f927c5ae
JB
334
335#ifdef VMS
f927c5ae
JB
336 LIB$STOP (SS$_ABORT);
337#else
8090eb09
JB
338 /* Signal the same code; this time it will really be fatal.
339 Remember that since we're in a signal handler, the signal we're
340 going to send is probably blocked, so we have to unblock it if we
341 want to really receive it. */
29b89fe0 342#ifndef MSDOS
a90538cb 343 sigunblock (sigmask (fatal_error_code));
29b89fe0 344#endif
f927c5ae
JB
345 kill (getpid (), fatal_error_code);
346#endif /* not VMS */
347}
271c7b7c
RS
348
349#ifdef SIGDANGER
350
16c323ee 351/* Handler for SIGDANGER. */
271c7b7c
RS
352SIGTYPE
353memory_warning_signal (sig)
354 int sig;
355{
356 signal (sig, memory_warning_signal);
357
358 malloc_warning ("Operating system warns that virtual memory is running low.\n");
55796183
RS
359
360 /* It might be unsafe to call do_auto_save now. */
361 force_auto_save_soon ();
271c7b7c
RS
362}
363#endif
fcf01ad3
RS
364
365/* We define abort, rather than using it from the library,
c9fe9cce
KH
366 so that GDB can return from a breakpoint here.
367 MSDOS has its own definition on msdos.c */
fcf01ad3 368
37e2fdd2 369#if ! defined (DOS_NT) && ! defined (NO_ABORT)
ca9c0567
PE
370
371#ifndef ABORT_RETURN_TYPE
372#define ABORT_RETURN_TYPE void
373#endif
374
375ABORT_RETURN_TYPE
fcf01ad3
RS
376abort ()
377{
378 kill (getpid (), SIGABRT);
37e2fdd2
RS
379 /* This shouldn't be executed, but it prevents a warning. */
380 exit (1);
fcf01ad3 381}
c9fe9cce 382#endif
fcf01ad3 383
f927c5ae
JB
384\f
385/* Code for dealing with Lisp access to the Unix command line */
386
dfcf069d 387static void
f927c5ae
JB
388init_cmdargs (argc, argv, skip_args)
389 int argc;
390 char **argv;
391 int skip_args;
392{
393 register int i;
213d0b1f
RS
394 Lisp_Object name, dir, tem;
395 int count = specpdl_ptr - specpdl;
396 Lisp_Object raw_name;
f927c5ae 397
e29f86e4
RS
398 initial_argv = argv;
399 initial_argc = argc;
400
213d0b1f
RS
401 raw_name = build_string (argv[0]);
402
403 /* Add /: to the front of the name
404 if it would otherwise be treated as magic. */
405 tem = Ffind_file_name_handler (raw_name, Qt);
406 if (! NILP (tem))
407 raw_name = concat2 (build_string ("/:"), raw_name);
408
409 Vinvocation_name = Ffile_name_nondirectory (raw_name);
410 Vinvocation_directory = Ffile_name_directory (raw_name);
411
ace40a69
RS
412 /* If we got no directory in argv[0], search PATH to find where
413 Emacs actually came from. */
414 if (NILP (Vinvocation_directory))
415 {
416 Lisp_Object found;
417 int yes = openp (Vexec_path, Vinvocation_name,
6c362a8b 418 EXEC_SUFFIXES, &found, 1);
e443f843 419 if (yes == 1)
213d0b1f
RS
420 {
421 /* Add /: to the front of the name
422 if it would otherwise be treated as magic. */
423 tem = Ffind_file_name_handler (found, Qt);
424 if (! NILP (tem))
425 found = concat2 (build_string ("/:"), found);
426 Vinvocation_directory = Ffile_name_directory (found);
427 }
ace40a69 428 }
59653951 429
4133b300
RS
430 if (!NILP (Vinvocation_directory)
431 && NILP (Ffile_name_absolute_p (Vinvocation_directory)))
213d0b1f
RS
432 /* Emacs was started with relative path, like ./emacs.
433 Make it absolute. */
4133b300
RS
434 Vinvocation_directory = Fexpand_file_name (Vinvocation_directory, Qnil);
435
07f4d123
RS
436 Vinstallation_directory = Qnil;
437
438 if (!NILP (Vinvocation_directory))
439 {
440 dir = Vinvocation_directory;
441 name = Fexpand_file_name (Vinvocation_name, dir);
442 while (1)
443 {
f5ab9736 444 Lisp_Object tem, lib_src_exists;
07f4d123
RS
445 Lisp_Object etc_exists, info_exists;
446
f5ab9736
RS
447 /* See if dir contains subdirs for use by Emacs.
448 Check for the ones that would exist in a build directory,
449 not including lisp and info. */
450 tem = Fexpand_file_name (build_string ("lib-src"), dir);
451 lib_src_exists = Ffile_exists_p (tem);
de004cc6 452
70344b34 453#ifdef MSDOS
de004cc6
RS
454 /* MSDOS installations frequently remove lib-src, but we still
455 must set installation-directory, or else info won't find
456 its files (it uses the value of installation-directory). */
457 tem = Fexpand_file_name (build_string ("info"), dir);
458 info_exists = Ffile_exists_p (tem);
70344b34
EZ
459#else
460 info_exists = Qnil;
461#endif
de004cc6
RS
462
463 if (!NILP (lib_src_exists) || !NILP (info_exists))
07f4d123 464 {
f5ab9736
RS
465 tem = Fexpand_file_name (build_string ("etc"), dir);
466 etc_exists = Ffile_exists_p (tem);
467 if (!NILP (etc_exists))
07f4d123 468 {
f5ab9736
RS
469 Vinstallation_directory
470 = Ffile_name_as_directory (dir);
471 break;
07f4d123
RS
472 }
473 }
474
475 /* See if dir's parent contains those subdirs. */
f5ab9736
RS
476 tem = Fexpand_file_name (build_string ("../lib-src"), dir);
477 lib_src_exists = Ffile_exists_p (tem);
de004cc6 478
70344b34
EZ
479
480#ifdef MSDOS
481 /* See the MSDOS commentary above. */
de004cc6
RS
482 tem = Fexpand_file_name (build_string ("../info"), dir);
483 info_exists = Ffile_exists_p (tem);
70344b34
EZ
484#else
485 info_exists = Qnil;
486#endif
de004cc6
RS
487
488 if (!NILP (lib_src_exists) || !NILP (info_exists))
07f4d123 489 {
f5ab9736
RS
490 tem = Fexpand_file_name (build_string ("../etc"), dir);
491 etc_exists = Ffile_exists_p (tem);
492 if (!NILP (etc_exists))
07f4d123 493 {
f5ab9736
RS
494 tem = Fexpand_file_name (build_string (".."), dir);
495 Vinstallation_directory
496 = Ffile_name_as_directory (tem);
497 break;
07f4d123
RS
498 }
499 }
500
501 /* If the Emacs executable is actually a link,
502 next try the dir that the link points into. */
503 tem = Ffile_symlink_p (name);
504 if (!NILP (tem))
505 {
260ec24d 506 name = Fexpand_file_name (tem, dir);
07f4d123
RS
507 dir = Ffile_name_directory (name);
508 }
509 else
510 break;
511 }
512 }
513
f927c5ae
JB
514 Vcommand_line_args = Qnil;
515
516 for (i = argc - 1; i >= 0; i--)
517 {
518 if (i == 0 || i > skip_args)
519 Vcommand_line_args
520 = Fcons (build_string (argv[i]), Vcommand_line_args);
521 }
213d0b1f
RS
522
523 unbind_to (count, Qnil);
f927c5ae 524}
59653951
JB
525
526DEFUN ("invocation-name", Finvocation_name, Sinvocation_name, 0, 0, 0,
527 "Return the program name that was used to run Emacs.\n\
528Any directory names are omitted.")
529 ()
530{
531 return Fcopy_sequence (Vinvocation_name);
532}
533
ace40a69
RS
534DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory,
535 0, 0, 0,
536 "Return the directory name in which the Emacs executable was located")
537 ()
538{
539 return Fcopy_sequence (Vinvocation_directory);
540}
541
f927c5ae
JB
542\f
543#ifdef VMS
544#ifdef LINK_CRTL_SHARE
34035df3 545#ifdef SHARABLE_LIB_BUG
f927c5ae 546extern noshare char **environ;
34035df3 547#endif /* SHARABLE_LIB_BUG */
f927c5ae
JB
548#endif /* LINK_CRTL_SHARE */
549#endif /* VMS */
550
0269dedb
RS
551#ifdef HAVE_TZSET
552/* A valid but unlikely value for the TZ environment value.
553 It is OK (though a bit slower) if the user actually chooses this value. */
554static char dump_tz[] = "UtC0";
555#endif
556
a90538cb 557#ifndef ORDINARY_LINK
efd241cc
RS
558/* We don't include crtbegin.o and crtend.o in the link,
559 so these functions and variables might be missed.
560 Provide dummy definitions to avoid error.
561 (We don't have any real constructors or destructors.) */
562#ifdef __GNUC__
46e65b73 563#ifndef GCC_CTORS_IN_LIBC
dfcf069d 564void __do_global_ctors ()
efd241cc 565{}
dfcf069d 566void __do_global_ctors_aux ()
c83a7064 567{}
dfcf069d 568void __do_global_dtors ()
33143604 569{}
64c1864a
RS
570/* Linux has a bug in its library; avoid an error. */
571#ifndef LINUX
c83a7064 572char * __CTOR_LIST__[2] = { (char *) (-1), 0 };
64c1864a 573#endif
c83a7064 574char * __DTOR_LIST__[2] = { (char *) (-1), 0 };
46e65b73 575#endif /* GCC_CTORS_IN_LIBC */
dfcf069d 576void __main ()
efd241cc 577{}
efd241cc 578#endif /* __GNUC__ */
a90538cb 579#endif /* ORDINARY_LINK */
efd241cc 580
e2925360
KH
581/* Test whether the next argument in ARGV matches SSTR or a prefix of
582 LSTR (at least MINLEN characters). If so, then if VALPTR is non-null
583 (the argument is supposed to have a value) store in *VALPTR either
584 the next argument or the portion of this one after the equal sign.
585 ARGV is read starting at position *SKIPPTR; this index is advanced
586 by the number of arguments used.
587
588 Too bad we can't just use getopt for all of this, but we don't have
589 enough information to do it right. */
081bef73 590
e2925360 591static int
df6530f8 592argmatch (argv, argc, sstr, lstr, minlen, valptr, skipptr)
e2925360 593 char **argv;
df6530f8 594 int argc;
e2925360
KH
595 char *sstr;
596 char *lstr;
597 int minlen;
598 char **valptr;
599 int *skipptr;
600{
601 char *p;
602 int arglen;
df6530f8
RS
603 char *arg;
604
605 /* Don't access argv[argc]; give up in advance. */
606 if (argc <= *skipptr + 1)
607 return 0;
608
609 arg = argv[*skipptr+1];
e2925360
KH
610 if (arg == NULL)
611 return 0;
612 if (strcmp (arg, sstr) == 0)
613 {
614 if (valptr != NULL)
615 {
616 *valptr = argv[*skipptr+2];
617 *skipptr += 2;
618 }
619 else
620 *skipptr += 1;
621 return 1;
622 }
623 arglen = (valptr != NULL && (p = index (arg, '=')) != NULL
624 ? p - arg : strlen (arg));
c03e1113 625 if (lstr == 0 || arglen < minlen || strncmp (arg, lstr, arglen) != 0)
e2925360
KH
626 return 0;
627 else if (valptr == NULL)
628 {
629 *skipptr += 1;
630 return 1;
631 }
632 else if (p != NULL)
633 {
634 *valptr = p+1;
635 *skipptr += 1;
636 return 1;
637 }
638 else if (argv[*skipptr+2] != NULL)
639 {
640 *valptr = argv[*skipptr+2];
641 *skipptr += 2;
642 return 1;
643 }
644 else
645 {
646 return 0;
647 }
648}
649
b6779252 650#ifdef DOUG_LEA_MALLOC
f927c5ae 651
b6779252
KH
652/* malloc can be invoked even before main (e.g. by the dynamic
653 linker), so the dumped malloc state must be restored as early as
654 possible using this special hook. */
655
656static void
657malloc_initialize_hook ()
658{
659 extern char **environ;
6000fe37 660
15aaf1b5
RS
661 if (initialized)
662 {
7c9cd446
AS
663 if (!malloc_using_checking)
664 /* Work around a bug in glibc's malloc. MALLOC_CHECK_ must be
665 ignored if the heap to be restored was constructed without
d942e12a
AS
666 malloc checking. Can't use unsetenv, since that calls malloc. */
667 {
668 char **p;
669
b6779252 670 for (p = environ; *p; p++)
d942e12a
AS
671 if (strncmp (*p, "MALLOC_CHECK_=", 14) == 0)
672 {
673 do
674 *p = p[1];
675 while (*++p);
676 break;
677 }
678 }
b6779252 679
15aaf1b5
RS
680 malloc_set_state (malloc_state_ptr);
681 free (malloc_state_ptr);
682 }
7c9cd446
AS
683 else
684 malloc_using_checking = getenv ("MALLOC_CHECK_") != NULL;
b6779252
KH
685}
686
687void (*__malloc_initialize_hook) () = malloc_initialize_hook;
688
689#endif /* DOUG_LEA_MALLOC */
690
691/* ARGSUSED */
692int
693main (argc, argv, envp)
694 int argc;
695 char **argv;
696 char **envp;
697{
2313132f 698#if GC_MARK_STACK
39ec21ea
GM
699 Lisp_Object dummy;
700#endif
b6779252 701 char stack_bottom_variable;
68c45bf0 702 int do_initial_setlocale;
b6779252
KH
703 int skip_args = 0;
704 extern int errno;
705 extern int sys_nerr;
706#ifdef HAVE_SETRLIMIT
707 struct rlimit rlim;
708#endif
709 int no_loadup = 0;
710
2313132f 711#if GC_MARK_STACK
39ec21ea
GM
712 extern Lisp_Object *stack_base;
713 stack_base = &dummy;
714#endif
715
b6779252
KH
716#ifdef LINUX_SBRK_BUG
717 __sbrk (1);
15aaf1b5
RS
718#endif
719
d785cf9e
RS
720#ifdef RUN_TIME_REMAP
721 if (initialized)
722 run_time_remap (argv[0]);
723#endif
724
081bef73 725 sort_args (argc, argv);
956e3c7e
RS
726 argc = 0;
727 while (argv[argc]) argc++;
081bef73 728
3270ae6e
KH
729 if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args)
730 /* We don't know the version number unless this is a dumped Emacs.
731 So ignore --version otherwise. */
732 && initialized)
1702afef
RS
733 {
734 Lisp_Object tem;
735 tem = Fsymbol_value (intern ("emacs-version"));
736 if (!STRINGP (tem))
737 {
738 fprintf (stderr, "Invalid value of `emacs-version'\n");
739 exit (1);
740 }
741 else
742 {
30ce1583 743 printf ("GNU Emacs %s\n", XSTRING (tem)->data);
7e8e59d0 744 printf ("Copyright (C) 1999 Free Software Foundation, Inc.\n");
b455c665
RS
745 printf ("GNU Emacs comes with ABSOLUTELY NO WARRANTY.\n");
746 printf ("You may redistribute copies of Emacs\n");
747 printf ("under the terms of the GNU General Public License.\n");
748 printf ("For more information about these matters, ");
94487c4e 749 printf ("see the file named COPYING.\n");
1702afef
RS
750 exit (0);
751 }
752 }
753
f927c5ae
JB
754/* Map in shared memory, if we are using that. */
755#ifdef HAVE_SHM
df6530f8 756 if (argmatch (argv, argc, "-nl", "--no-shared-memory", 6, NULL, &skip_args))
f927c5ae
JB
757 {
758 map_in_data (0);
759 /* The shared memory was just restored, which clobbered this. */
760 skip_args = 1;
761 }
762 else
763 {
764 map_in_data (1);
765 /* The shared memory was just restored, which clobbered this. */
766 skip_args = 0;
767 }
768#endif
769
19a36ec6 770#ifdef NeXT
b9df9faa
KH
771 {
772 extern int malloc_cookie;
773 /* This helps out unexnext.c. */
774 if (initialized)
775 if (malloc_jumpstart (malloc_cookie) != 0)
776 printf ("malloc jumpstart failed!\n");
777 }
19a36ec6
RS
778#endif /* NeXT */
779
f927c5ae
JB
780#ifdef VMS
781 /* If -map specified, map the data file in */
e2925360
KH
782 {
783 char *file;
df6530f8 784 if (argmatch (argv, argc, "-map", "--map-data", 3, &mapin_file, &skip_args))
e2925360
KH
785 mapin_data (file);
786 }
f927c5ae
JB
787
788#ifdef LINK_CRTL_SHARE
34035df3 789#ifdef SHARABLE_LIB_BUG
f927c5ae
JB
790 /* Bletcherous shared libraries! */
791 if (!stdin)
792 stdin = fdopen (0, "r");
793 if (!stdout)
794 stdout = fdopen (1, "w");
795 if (!stderr)
796 stderr = fdopen (2, "w");
797 if (!environ)
798 environ = envp;
34035df3 799#endif /* SHARABLE_LIB_BUG */
f927c5ae
JB
800#endif /* LINK_CRTL_SHARE */
801#endif /* VMS */
802
ea2acec5 803#if defined (HAVE_SETRLIMIT) && defined (RLIMIT_STACK)
6c2935e9
RS
804 /* Extend the stack space available.
805 Don't do that if dumping, since some systems (e.g. DJGPP)
806 might define a smaller stack limit at that time. */
807 if (1
808#ifndef CANNOT_DUMP
809 && (!noninteractive || initialized)
810#endif
811 && !getrlimit (RLIMIT_STACK, &rlim))
53c58b5d 812 {
509a8fcd 813 long newlim;
6c2935e9 814 extern int re_max_failures;
03effc23
KH
815 /* Approximate the amount regex.c needs per unit of re_max_failures. */
816 int ratio = 20 * sizeof (char *);
817 /* Then add 33% to cover the size of the smaller stacks that regex.c
818 successively allocates and discards, on its way to the maximum. */
819 ratio += ratio / 3;
820 /* Add in some extra to cover
821 what we're likely to use for other reasons. */
822 newlim = re_max_failures * ratio + 200000;
d0381a7f
RS
823#ifdef __NetBSD__
824 /* NetBSD (at least NetBSD 1.2G and former) has a bug in its
825 stack allocation routine for new process that the allocation
826 fails if stack limit is not on page boundary. So, round up the
827 new limit to page boundary. */
828 newlim = (newlim + getpagesize () - 1) / getpagesize () * getpagesize();
829#endif
509a8fcd 830 if (newlim > rlim.rlim_max)
6c2935e9
RS
831 {
832 newlim = rlim.rlim_max;
03effc23
KH
833 /* Don't let regex.c overflow the stack we have. */
834 re_max_failures = (newlim - 200000) / ratio;
6c2935e9 835 }
509a8fcd
RS
836 if (rlim.rlim_cur < newlim)
837 rlim.rlim_cur = newlim;
838
53c58b5d
RS
839 setrlimit (RLIMIT_STACK, &rlim);
840 }
ea2acec5 841#endif /* HAVE_SETRLIMIT and RLIMIT_STACK */
53c58b5d 842
f927c5ae
JB
843 /* Record (approximately) where the stack begins. */
844 stack_bottom = &stack_bottom_variable;
845
f927c5ae
JB
846#ifdef USG_SHARED_LIBRARIES
847 if (bss_end)
1d233b80 848 brk ((void *)bss_end);
f927c5ae
JB
849#endif
850
851 clearerr (stdin);
9ae8f997 852
f927c5ae 853#ifndef SYSTEM_MALLOC
bf7f4e90
RS
854 /* Arrange to get warning messages as memory fills up. */
855 memory_warnings (0, malloc_warning);
9ac0d9e0 856
f5a3c8c4
AI
857 /* Call malloc at least once, to run the initial __malloc_hook.
858 Also call realloc and free for consistency. */
859 free (realloc (malloc (4), 4));
bf7f4e90
RS
860
861 /* Arrange to disable interrupt input inside malloc etc. */
862 uninterrupt_malloc ();
f927c5ae
JB
863#endif /* not SYSTEM_MALLOC */
864
29b89fe0
RS
865#ifdef MSDOS
866 /* We do all file input/output as binary files. When we need to translate
867 newlines, we do that manually. */
868 _fmode = O_BINARY;
18198bb2
RS
869
870#if __DJGPP__ >= 2
871 if (!isatty (fileno (stdin)))
872 setmode (fileno (stdin), O_BINARY);
873 if (!isatty (fileno (stdout)))
874 {
875 fflush (stdout);
876 setmode (fileno (stdout), O_BINARY);
877 }
878#else /* not __DJGPP__ >= 2 */
29b89fe0
RS
879 (stdin)->_flag &= ~_IOTEXT;
880 (stdout)->_flag &= ~_IOTEXT;
881 (stderr)->_flag &= ~_IOTEXT;
18198bb2 882#endif /* not __DJGPP__ >= 2 */
29b89fe0
RS
883#endif /* MSDOS */
884
a422068f 885#ifdef SET_EMACS_PRIORITY
3005da00 886 if (emacs_priority)
5aa7f46a 887 nice (emacs_priority);
f927c5ae 888 setuid (getuid ());
a422068f 889#endif /* SET_EMACS_PRIORITY */
f927c5ae 890
68c45bf0
PE
891 /* Skip initial setlocale if LC_ALL is "C", as it's not needed in that case.
892 The build procedure uses this while dumping, to ensure that the
893 dumped Emacs does not have its system locale tables initialized,
894 as that might cause screwups when the dumped Emacs starts up. */
895 {
896 char *lc_all = getenv ("LC_ALL");
897 do_initial_setlocale = ! lc_all || strcmp (lc_all, "C");
898 }
899
900 /* Set locale now, so that initial error messages are localized properly.
901 fixup_locale must wait until later, since it builds strings. */
902 if (do_initial_setlocale)
903 setlocale (LC_ALL, "");
904
d8b3a65d 905#ifdef EXTRA_INITIALIZE
a9260219 906 EXTRA_INITIALIZE;
d8b3a65d
RS
907#endif
908
f927c5ae
JB
909 inhibit_window_system = 0;
910
4fc0b45b 911 /* Handle the -t switch, which specifies filename to use as terminal */
956e3c7e
RS
912 while (1)
913 {
914 char *term;
915 if (argmatch (argv, argc, "-t", "--terminal", 4, &term, &skip_args))
916 {
917 int result;
68c45bf0
PE
918 emacs_close (0);
919 emacs_close (1);
920 result = emacs_open (term, O_RDWR, 0);
956e3c7e
RS
921 if (result < 0)
922 {
923 char *errstring = strerror (errno);
924 fprintf (stderr, "emacs: %s: %s\n", term, errstring);
925 exit (1);
926 }
927 dup (0);
928 if (! isatty (0))
929 {
930 fprintf (stderr, "emacs: %s: not a tty\n", term);
931 exit (1);
932 }
933 fprintf (stderr, "Using %s\n", term);
8ba50e1a 934#ifdef HAVE_WINDOW_SYSTEM
956e3c7e 935 inhibit_window_system = 1; /* -t => -nw */
f927c5ae 936#endif
956e3c7e
RS
937 }
938 else
939 break;
940 }
941
df6530f8 942 if (argmatch (argv, argc, "-nw", "--no-windows", 6, NULL, &skip_args))
e2925360 943 inhibit_window_system = 1;
f927c5ae 944
e2925360 945 /* Handle the -batch switch, which means don't do interactive display. */
f927c5ae 946 noninteractive = 0;
df6530f8 947 if (argmatch (argv, argc, "-batch", "--batch", 5, NULL, &skip_args))
e2925360
KH
948 noninteractive = 1;
949
950 /* Handle the --help option, which gives a usage message.. */
df6530f8 951 if (argmatch (argv, argc, "-help", "--help", 3, NULL, &skip_args))
f927c5ae 952 {
73ebcd25
AI
953 printf (USAGE1, argv[0]);
954 printf (USAGE2);
e2925360 955 exit (0);
f927c5ae
JB
956 }
957
edb85f59
RS
958 if (! noninteractive)
959 {
960#ifdef BSD_PGRPS
961 if (initialized)
962 {
963 inherited_pgroup = EMACS_GETPGRP (0);
964 setpgrp (0, getpid ());
965 }
966#else
967#if defined (USG5) && defined (INTERRUPT_INPUT)
968 setpgrp ();
969#endif
970#endif
971 }
972
fb8e9847 973 init_signals ();
fb8e9847 974
1efa2983
KH
975 /* Don't catch SIGHUP if dumping. */
976 if (1
977#ifndef CANNOT_DUMP
978 && initialized
979#endif
980 )
981 {
57e3d22a 982 sigblock (sigmask (SIGHUP));
1efa2983
KH
983 /* In --batch mode, don't catch SIGHUP if already ignored.
984 That makes nohup work. */
985 if (! noninteractive
986 || signal (SIGHUP, SIG_IGN) != SIG_IGN)
987 signal (SIGHUP, fatal_error_signal);
57e3d22a 988 sigunblock (sigmask (SIGHUP));
1efa2983
KH
989 }
990
f927c5ae
JB
991 if (
992#ifndef CANNOT_DUMP
993 ! noninteractive || initialized
994#else
995 1
996#endif
997 )
998 {
1efa2983 999 /* Don't catch these signals in batch mode if dumping.
f927c5ae
JB
1000 On some machines, this sets static data that would make
1001 signal fail to work right when the dumped Emacs is run. */
f927c5ae
JB
1002 signal (SIGQUIT, fatal_error_signal);
1003 signal (SIGILL, fatal_error_signal);
1004 signal (SIGTRAP, fatal_error_signal);
7317d9e8
RS
1005#ifdef SIGUSR1
1006 signal (SIGUSR1, handle_USR1_signal);
1007#ifdef SIGUSR2
1008 signal (SIGUSR2, handle_USR2_signal);
1009#endif
1010#endif
99e372cd
RS
1011#ifdef SIGABRT
1012 signal (SIGABRT, fatal_error_signal);
1013#endif
1014#ifdef SIGHWE
1015 signal (SIGHWE, fatal_error_signal);
1016#endif
1017#ifdef SIGPRE
1018 signal (SIGPRE, fatal_error_signal);
1019#endif
1020#ifdef SIGORE
1021 signal (SIGORE, fatal_error_signal);
1022#endif
1023#ifdef SIGUME
1024 signal (SIGUME, fatal_error_signal);
1025#endif
1026#ifdef SIGDLK
1027 signal (SIGDLK, fatal_error_signal);
1028#endif
1029#ifdef SIGCPULIM
1030 signal (SIGCPULIM, fatal_error_signal);
1031#endif
a90538cb
JB
1032#ifdef SIGIOT
1033 /* This is missing on some systems - OS/2, for example. */
f927c5ae 1034 signal (SIGIOT, fatal_error_signal);
a90538cb 1035#endif
f927c5ae
JB
1036#ifdef SIGEMT
1037 signal (SIGEMT, fatal_error_signal);
1038#endif
1039 signal (SIGFPE, fatal_error_signal);
00eaaa32 1040#ifdef SIGBUS
f927c5ae 1041 signal (SIGBUS, fatal_error_signal);
00eaaa32 1042#endif
f927c5ae 1043 signal (SIGSEGV, fatal_error_signal);
00eaaa32 1044#ifdef SIGSYS
f927c5ae 1045 signal (SIGSYS, fatal_error_signal);
00eaaa32 1046#endif
f927c5ae
JB
1047 signal (SIGTERM, fatal_error_signal);
1048#ifdef SIGXCPU
1049 signal (SIGXCPU, fatal_error_signal);
1050#endif
1051#ifdef SIGXFSZ
1052 signal (SIGXFSZ, fatal_error_signal);
1053#endif /* SIGXFSZ */
1054
271c7b7c
RS
1055#ifdef SIGDANGER
1056 /* This just means available memory is getting low. */
1057 signal (SIGDANGER, memory_warning_signal);
1058#endif
1059
f927c5ae 1060#ifdef AIX
56e034fa
RS
1061/* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */
1062 signal (SIGXCPU, fatal_error_signal);
0aef8561 1063#ifndef _I386
f927c5ae 1064 signal (SIGIOINT, fatal_error_signal);
0aef8561 1065#endif
f927c5ae
JB
1066 signal (SIGGRANT, fatal_error_signal);
1067 signal (SIGRETRACT, fatal_error_signal);
1068 signal (SIGSOUND, fatal_error_signal);
1069 signal (SIGMSG, fatal_error_signal);
1070#endif /* AIX */
1071 }
1072
1073 noninteractive1 = noninteractive;
1074
1075/* Perform basic initializations (not merely interning symbols) */
1076
1077 if (!initialized)
1078 {
1079 init_alloc_once ();
1080 init_obarray ();
1081 init_eval_once ();
270ce821
KH
1082 init_charset_once ();
1083 init_coding_once ();
f927c5ae 1084 init_syntax_once (); /* Create standard syntax table. */
270ce821 1085 init_category_once (); /* Create standard category table. */
f927c5ae
JB
1086 /* Must be done before init_buffer */
1087 init_casetab_once ();
1088 init_buffer_once (); /* Create buffer table and some buffers */
1089 init_minibuf_once (); /* Create list of minibuffers */
90d920b6
GM
1090 /* Must precede init_window_once */
1091
1092 /* Call syms_of_xfaces before init_window_once because that
1093 function creates Vterminal_frame. Termcap frames now use
1094 faces, and the face implementation uses some symbols as
1095 face names. */
90d920b6 1096 syms_of_xfaces ();
90d920b6 1097
f927c5ae 1098 init_window_once (); /* Init the window system */
680256a8 1099 init_fileio_once (); /* Must precede any path manipulation. */
f927c5ae
JB
1100 }
1101
1102 init_alloc ();
68c45bf0
PE
1103
1104 if (do_initial_setlocale)
1105 {
1106 fixup_locale ();
ca9c0567
PE
1107 Vsystem_messages_locale = Vprevious_system_messages_locale;
1108 Vsystem_time_locale = Vprevious_system_time_locale;
68c45bf0
PE
1109 }
1110
f927c5ae 1111 init_eval ();
0968d4ee 1112 init_coding ();
f927c5ae 1113 init_data ();
ad067ea6
KH
1114#ifdef CLASH_DETECTION
1115 init_filelock ();;
1116#endif
ab5d0358 1117 init_atimer ();
7074fde6 1118 running_asynch_code = 0;
0e956009 1119
a08a816a
RS
1120 /* Handle --unibyte and the EMACS_UNIBYTE envvar,
1121 but not while dumping. */
1122 if (
1123#ifndef CANNOT_DUMP
1124 ! noninteractive || initialized
1125#else
1126 1
1127#endif
1128 )
1129 {
1130 int inhibit_unibyte = 0;
1131
1132 /* --multibyte overrides EMACS_UNIBYTE. */
1133 if (argmatch (argv, argc, "-no-unibyte", "--no-unibyte", 4, NULL, &skip_args)
1134 || argmatch (argv, argc, "-multibyte", "--multibyte", 4, NULL, &skip_args))
1135 inhibit_unibyte = 1;
1136
1137 /* --unibyte requests that we set up to do everything with single-byte
1138 buffers and strings. We need to handle this before calling
1139 init_lread, init_editfns and other places that generate Lisp strings
1140 from text in the environment. */
c0218e1b
DL
1141 /* Actually this shouldn't be needed as of 20.4 in a generally
1142 unibyte environment. As handa says, environment values
1143 aren't now decoded; also existing buffers are now made
1144 unibyte during startup if .emacs sets unibyte. Tested with
1145 8-bit data in environment variables and /etc/passwd, setting
1146 unibyte and Latin-1 in .emacs. -- Dave Love */
a08a816a
RS
1147 if (argmatch (argv, argc, "-unibyte", "--unibyte", 4, NULL, &skip_args)
1148 || argmatch (argv, argc, "-no-multibyte", "--no-multibyte", 4, NULL, &skip_args)
1149 || (getenv ("EMACS_UNIBYTE") && !inhibit_unibyte))
1150 {
1151 Lisp_Object old_log_max;
1152 Lisp_Object symbol, tail;
1153
1154 symbol = intern ("default-enable-multibyte-characters");
1155 Fset (symbol, Qnil);
1156
6524291c
KH
1157 if (initialized)
1158 {
1159 /* Erase pre-dump messages in *Messages* now so no abort. */
1160 old_log_max = Vmessage_log_max;
1161 XSETFASTINT (Vmessage_log_max, 0);
1162 message_dolog ("", 0, 1, 0);
1163 Vmessage_log_max = old_log_max;
1164 }
a08a816a 1165
3e75bb9e 1166 for (tail = Vbuffer_alist; CONSP (tail);
7539e11f 1167 tail = XCDR (tail))
a08a816a
RS
1168 {
1169 Lisp_Object buffer;
1170
7539e11f 1171 buffer = Fcdr (XCAR (tail));
a08a816a
RS
1172 /* Verify that all buffers are empty now, as they
1173 ought to be. */
1174 if (BUF_Z (XBUFFER (buffer)) > BUF_BEG (XBUFFER (buffer)))
1175 abort ();
1176 /* It is safe to do this crudely in an empty buffer. */
1177 XBUFFER (buffer)->enable_multibyte_characters = Qnil;
1178 }
1179 }
1180 }
1181
956e3c7e 1182 no_loadup
b96f9fb7 1183 = argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args);
956e3c7e
RS
1184
1185
1186#ifdef HAVE_X_WINDOWS
1187 /* Stupid kludge to catch command-line display spec. We can't
1188 handle this argument entirely in window system dependent code
1189 because we don't even know which window system dependent code
1190 to run until we've recognized this argument. */
1191 {
1192 char *displayname = 0;
956e3c7e
RS
1193 int count_before = skip_args;
1194
1195 /* Skip any number of -d options, but only use the last one. */
1196 while (1)
1197 {
1198 int count_before_this = skip_args;
1199
1200 if (argmatch (argv, argc, "-d", "--display", 3, &displayname, &skip_args))
1201 display_arg = 1;
1202 else if (argmatch (argv, argc, "-display", 0, 3, &displayname, &skip_args))
1203 display_arg = 1;
1204 else
1205 break;
1206
1207 count_before = count_before_this;
1208 }
1209
1210 /* If we have the form --display=NAME,
1211 convert it into -d name.
1212 This requires inserting a new element into argv. */
1213 if (displayname != 0 && skip_args - count_before == 1)
1214 {
1215 char **new = (char **) xmalloc (sizeof (char *) * (argc + 2));
1216 int j;
1217
1218 for (j = 0; j < count_before + 1; j++)
1219 new[j] = argv[j];
1220 new[count_before + 1] = "-d";
1221 new[count_before + 2] = displayname;
1222 for (j = count_before + 2; j <argc; j++)
1223 new[j + 1] = argv[j];
1224 argv = new;
1225 argc++;
1226 }
1227 /* Change --display to -d, when its arg is separate. */
1228 else if (displayname != 0 && skip_args > count_before
1229 && argv[count_before + 1][1] == '-')
1230 argv[count_before + 1] = "-d";
1231
1232 /* Don't actually discard this arg. */
1233 skip_args = count_before;
1234 }
1235#endif
1236
1237 /* argmatch must not be used after here,
1238 except when bulding temacs
1239 because the -d argument has not been skipped in skip_args. */
1240
29b89fe0
RS
1241#ifdef MSDOS
1242 /* Call early 'cause init_environment needs it. */
1243 init_dosfns ();
1244 /* Set defaults for several environment variables. */
18198bb2
RS
1245 if (initialized)
1246 init_environment (argc, argv, skip_args);
1247 else
d1fc6752 1248 tzset ();
18198bb2 1249#endif /* MSDOS */
29b89fe0 1250
8ba50e1a
GV
1251#ifdef WINDOWSNT
1252 /* Initialize environment from registry settings. */
a3a58294 1253 init_environment (argv);
41f339d4 1254 init_ntproc (); /* must precede init_editfns */
8ba50e1a
GV
1255#endif
1256
0e956009
JB
1257 /* egetenv is a pretty low-level facility, which may get called in
1258 many circumstances; it seems flimsy to put off initializing it
1259 until calling init_callproc. */
1260 set_process_environment ();
93aed04d
RS
1261 /* AIX crashes are reported in system versions 3.2.3 and 3.2.4
1262 if this is not done. Do it after set_process_environment so that we
1263 don't pollute Vprocess_environment. */
fa09a82d
DL
1264 /* Setting LANG here will defeat the startup locale processing... */
1265#ifdef AIX3_2
93aed04d
RS
1266 putenv ("LANG=C");
1267#endif
0e956009 1268
ace40a69
RS
1269 init_buffer (); /* Init default directory of main buffer */
1270
7928f0b5 1271 init_callproc_1 (); /* Must precede init_cmdargs and init_sys_modes. */
ace40a69 1272 init_cmdargs (argc, argv, skip_args); /* Must precede init_lread. */
380e25b8
RS
1273
1274 if (initialized)
1275 {
1276 /* Erase any pre-dump messages in the message log, to avoid confusion */
1277 Lisp_Object old_log_max;
1278 old_log_max = Vmessage_log_max;
1279 XSETFASTINT (Vmessage_log_max, 0);
f6fe7bb5 1280 message_dolog ("", 0, 1, 0);
380e25b8
RS
1281 Vmessage_log_max = old_log_max;
1282 }
1283
7928f0b5 1284 init_callproc (); /* Must follow init_cmdargs but not init_sys_modes. */
fb8e9847 1285 init_lread ();
f927c5ae 1286
8bb697c0
RS
1287 /* Intern the names of all standard functions and variables;
1288 define standard keys. */
f927c5ae
JB
1289
1290 if (!initialized)
1291 {
1292 /* The basic levels of Lisp must come first */
1293 /* And data must come first of all
1294 for the sake of symbols like error-message */
1295 syms_of_data ();
1296 syms_of_alloc ();
fb8e9847 1297 syms_of_lread ();
f927c5ae
JB
1298 syms_of_print ();
1299 syms_of_eval ();
1300 syms_of_fns ();
f927c5ae 1301 syms_of_floatfns ();
f927c5ae
JB
1302
1303 syms_of_abbrev ();
1304 syms_of_buffer ();
1305 syms_of_bytecode ();
1306 syms_of_callint ();
1307 syms_of_casefiddle ();
1308 syms_of_casetab ();
1309 syms_of_callproc ();
270ce821
KH
1310 syms_of_category ();
1311 syms_of_ccl ();
1312 syms_of_charset ();
f927c5ae
JB
1313 syms_of_cmds ();
1314#ifndef NO_DIR_LIBRARY
1315 syms_of_dired ();
1316#endif /* not NO_DIR_LIBRARY */
1317 syms_of_display ();
1318 syms_of_doc ();
1319 syms_of_editfns ();
1320 syms_of_emacs ();
1321 syms_of_fileio ();
270ce821 1322 syms_of_coding (); /* This should be after syms_of_fileio. */
f927c5ae
JB
1323#ifdef CLASH_DETECTION
1324 syms_of_filelock ();
1325#endif /* CLASH_DETECTION */
1326 syms_of_indent ();
c2c5ed2c 1327 syms_of_insdel ();
f927c5ae
JB
1328 syms_of_keyboard ();
1329 syms_of_keymap ();
1330 syms_of_macros ();
1331 syms_of_marker ();
1332 syms_of_minibuf ();
1333 syms_of_mocklisp ();
f927c5ae 1334 syms_of_process ();
f927c5ae 1335 syms_of_search ();
1cbd5d9d 1336 syms_of_frame ();
f927c5ae 1337 syms_of_syntax ();
0d934e7b 1338 syms_of_term ();
f927c5ae 1339 syms_of_undo ();
90d920b6
GM
1340#ifdef HAVE_SOUND
1341 syms_of_sound ();
1342#endif
bef79ee4 1343
bef79ee4 1344 syms_of_textprop ();
9d100795 1345 syms_of_composite ();
f927c5ae
JB
1346#ifdef VMS
1347 syms_of_vmsproc ();
1348#endif /* VMS */
05687c54
RS
1349#ifdef WINDOWSNT
1350 syms_of_ntproc ();
1351#endif /* WINDOWSNT */
f927c5ae
JB
1352 syms_of_window ();
1353 syms_of_xdisp ();
1354#ifdef HAVE_X_WINDOWS
72412588 1355 syms_of_xterm ();
f927c5ae 1356 syms_of_xfns ();
270ce821 1357 syms_of_fontset ();
72412588
JB
1358#ifdef HAVE_X11
1359 syms_of_xselect ();
1360#endif
f927c5ae
JB
1361#endif /* HAVE_X_WINDOWS */
1362
1e9c210b 1363#ifndef HAVE_NTGUI
6c850f3c 1364 syms_of_xmenu ();
1e9c210b 1365#endif
6c850f3c 1366
8ba50e1a 1367#ifdef HAVE_NTGUI
fbd6baed
GV
1368 syms_of_w32term ();
1369 syms_of_w32fns ();
fbd6baed
GV
1370 syms_of_w32select ();
1371 syms_of_w32menu ();
02062ac3 1372 syms_of_fontset ();
8ba50e1a
GV
1373#endif /* HAVE_NTGUI */
1374
f927c5ae
JB
1375#ifdef SYMS_SYSTEM
1376 SYMS_SYSTEM;
1377#endif
1378
1379#ifdef SYMS_MACHINE
1380 SYMS_MACHINE;
1381#endif
1382
1383 keys_of_casefiddle ();
1384 keys_of_cmds ();
1385 keys_of_buffer ();
1386 keys_of_keyboard ();
1387 keys_of_keymap ();
1388 keys_of_macros ();
1389 keys_of_minibuf ();
1390 keys_of_window ();
5e67fbc2 1391 keys_of_frame ();
f927c5ae
JB
1392 }
1393
8bb697c0
RS
1394 if (!noninteractive)
1395 {
1396#ifdef VMS
1397 init_vms_input ();/* init_display calls get_frame_size, that needs this */
1398#endif /* VMS */
1399 init_display (); /* Determine terminal type. init_sys_modes uses results */
1400 }
1401 init_keyboard (); /* This too must precede init_sys_modes */
1402#ifdef VMS
1403 init_vmsproc (); /* And this too. */
1404#endif /* VMS */
1405 init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.) */
90d920b6
GM
1406#ifdef HAVE_X_WINDOWS
1407 init_xfns ();
1408#endif /* HAVE_X_WINDOWS */
1409 init_fns ();
8bb697c0
RS
1410 init_xdisp ();
1411 init_macros ();
1412 init_editfns ();
8bb697c0 1413 init_floatfns ();
8bb697c0
RS
1414#ifdef VMS
1415 init_vmsfns ();
1416#endif /* VMS */
1417 init_process ();
90d920b6
GM
1418#ifdef HAVE_SOUND
1419 init_sound ();
1420#endif
8bb697c0 1421
f927c5ae
JB
1422 if (!initialized)
1423 {
e2925360 1424 char *file;
303901fb 1425 /* Handle -l loadup, args passed by Makefile. */
df6530f8 1426 if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args))
f927c5ae 1427 Vtop_level = Fcons (intern ("load"),
e2925360 1428 Fcons (build_string (file), Qnil));
f927c5ae
JB
1429#ifdef CANNOT_DUMP
1430 /* Unless next switch is -nl, load "loadup.el" first thing. */
956e3c7e 1431 if (! no_loadup)
f927c5ae
JB
1432 Vtop_level = Fcons (intern ("load"),
1433 Fcons (build_string ("loadup.el"), Qnil));
1434#endif /* CANNOT_DUMP */
1435 }
1436
93572b43
KH
1437 if (initialized)
1438 {
0269dedb
RS
1439#ifdef HAVE_TZSET
1440 {
1441 /* If the execution TZ happens to be the same as the dump TZ,
1442 change it to some other value and then change it back,
1443 to force the underlying implementation to reload the TZ info.
1444 This is needed on implementations that load TZ info from files,
1445 since the TZ file contents may differ between dump and execution. */
1446 char *tz = getenv ("TZ");
1447 if (tz && !strcmp (tz, dump_tz))
1448 {
1449 ++*tz;
1450 tzset ();
1451 --*tz;
1452 }
1453 }
1454#endif
93572b43
KH
1455 }
1456
e610ea43
RS
1457 /* Gerd Moellmann <gerd@acm.org> says this makes profiling work on
1458 FreeBSD. It might work on some other systems too.
1459 Give it a try and tell me if it works on your system. */
6a97197e 1460#if defined (__FreeBSD__) || defined (__linux)
e610ea43
RS
1461#ifdef PROFILING
1462 if (initialized)
1463 {
1464 extern void _mcleanup ();
1465 extern char etext;
90d920b6 1466 extern void safe_bcopy ();
67a5596f
GM
1467 extern void dump_opcode_frequencies ();
1468
e610ea43 1469 atexit (_mcleanup);
90d920b6
GM
1470 /* This uses safe_bcopy because that function comes first in the
1471 Emacs executable. It might be better to use something that
1472 gives the start of the text segment, but start_of_text is not
1473 defined on all systems now. */
1474 monstartup (safe_bcopy, &etext);
e610ea43
RS
1475 }
1476 else
1477 moncontrol (0);
1478#endif
1479#endif
1480
f927c5ae
JB
1481 initialized = 1;
1482
e7536cff
RS
1483#ifdef LOCALTIME_CACHE
1484 /* Some versions of localtime have a bug. They cache the value of the time
279cc2b8
JB
1485 zone rather than looking it up every time. Since localtime() is
1486 called to bolt the undumping time into the undumped emacs, this
afe9fae9
RS
1487 results in localtime ignoring the TZ environment variable.
1488 This flushes the new TZ value into localtime. */
1489 tzset ();
e7536cff 1490#endif /* defined (LOCALTIME_CACHE) */
279cc2b8 1491
f927c5ae
JB
1492 /* Enter editor command loop. This never returns. */
1493 Frecursive_edit ();
1494 /* NOTREACHED */
1495}
1496\f
081bef73
RS
1497/* Sort the args so we can find the most important ones
1498 at the beginning of argv. */
1499
1500/* First, here's a table of all the standard options. */
1501
1502struct standard_args
1503{
1504 char *name;
1505 char *longname;
1506 int priority;
1507 int nargs;
1508};
1509
1510struct standard_args standard_args[] =
1511{
05922407
RS
1512 { "-version", "--version", 150, 0 },
1513#ifdef HAVE_SHM
1514 { "-nl", "--no-shared-memory", 140, 0 },
1515#endif
2725719a 1516#ifdef VMS
05922407 1517 { "-map", "--map-data", 130, 0 },
2725719a 1518#endif
05922407
RS
1519 { "-t", "--terminal", 120, 1 },
1520 { "-nw", "--no-windows", 110, 0 },
1521 { "-batch", "--batch", 100, 0 },
1522 { "-help", "--help", 90, 0 },
956e3c7e
RS
1523 { "-no-unibyte", "--no-unibyte", 83, 0 },
1524 { "-multibyte", "--multibyte", 82, 0 },
1525 { "-unibyte", "--unibyte", 81, 0 },
1526 { "-no-multibyte", "--no-multibyte", 80, 0 },
05922407 1527#ifdef CANNOT_DUMP
956e3c7e 1528 { "-nl", "--no-loadup", 70, 0 },
05922407 1529#endif
956e3c7e
RS
1530 /* -d must come last before the options handled in startup.el. */
1531 { "-d", "--display", 60, 1 },
1532 { "-display", 0, 60, 1 },
05922407 1533 /* Now for the options handled in startup.el. */
081bef73
RS
1534 { "-q", "--no-init-file", 50, 0 },
1535 { "-no-init-file", 0, 50, 0 },
1536 { "-no-site-file", "--no-site-file", 40, 0 },
1537 { "-u", "--user", 30, 1 },
1538 { "-user", 0, 30, 1 },
1539 { "-debug-init", "--debug-init", 20, 0 },
adab4483
KH
1540 { "-i", "--icon-type", 15, 0 },
1541 { "-itype", 0, 15, 0 },
f2bc3538 1542 { "-iconic", "--iconic", 15, 0 },
081bef73
RS
1543 { "-bg", "--background-color", 10, 1 },
1544 { "-background", 0, 10, 1 },
1545 { "-fg", "--foreground-color", 10, 1 },
1546 { "-foreground", 0, 10, 1 },
1547 { "-bd", "--border-color", 10, 1 },
1548 { "-bw", "--border-width", 10, 1 },
1549 { "-ib", "--internal-border", 10, 1 },
1550 { "-ms", "--mouse-color", 10, 1 },
1551 { "-cr", "--cursor-color", 10, 1 },
1552 { "-fn", "--font", 10, 1 },
1553 { "-font", 0, 10, 1 },
1554 { "-g", "--geometry", 10, 1 },
1555 { "-geometry", 0, 10, 1 },
1556 { "-T", "--title", 10, 1 },
ae63ae52 1557 { "-title", 0, 10, 1 },
081bef73
RS
1558 { "-name", "--name", 10, 1 },
1559 { "-xrm", "--xrm", 10, 1 },
fcdeb5d9
RS
1560 { "-r", "--reverse-video", 5, 0 },
1561 { "-rv", 0, 5, 0 },
1562 { "-reverse", 0, 5, 0 },
ae63ae52 1563 { "-hb", "--horizontal-scroll-bars", 5, 0 },
fcdeb5d9 1564 { "-vb", "--vertical-scroll-bars", 5, 0 },
fcdeb5d9
RS
1565 /* These have the same priority as ordinary file name args,
1566 so they are not reordered with respect to those. */
4af9e0b3
RS
1567 { "-L", "--directory", 0, 1 },
1568 { "-directory", 0, 0, 1 },
fcdeb5d9
RS
1569 { "-l", "--load", 0, 1 },
1570 { "-load", 0, 0, 1 },
1571 { "-f", "--funcall", 0, 1 },
1572 { "-funcall", 0, 0, 1 },
575985b1 1573 { "-eval", "--eval", 0, 1 },
67a5596f 1574 { "-execute", "--execute", 0, 1 },
2e13f8e9
RS
1575 { "-find-file", "--find-file", 0, 1 },
1576 { "-visit", "--visit", 0, 1 },
67a5596f 1577 { "-file", "--file", 0, 1 },
fcdeb5d9 1578 { "-insert", "--insert", 0, 1 },
f2bc3538 1579 /* This should be processed after ordinary file name args and the like. */
fcdeb5d9 1580 { "-kill", "--kill", -10, 0 },
081bef73
RS
1581};
1582
1583/* Reorder the elements of ARGV (assumed to have ARGC elements)
1584 so that the highest priority ones come first.
1585 Do not change the order of elements of equal priority.
956e3c7e
RS
1586 If an option takes an argument, keep it and its argument together.
1587
1588 If an option that takes no argument appears more
1589 than once, eliminate all but one copy of it. */
081bef73
RS
1590
1591static void
1592sort_args (argc, argv)
1593 int argc;
1594 char **argv;
1595{
1596 char **new = (char **) xmalloc (sizeof (char *) * argc);
1597 /* For each element of argv,
1598 the corresponding element of options is:
1599 0 for an option that takes no arguments,
1600 1 for an option that takes one argument, etc.
1601 -1 for an ordinary non-option argument. */
6dad9359 1602 int *options = (int *) xmalloc (sizeof (int) * argc);
081bef73
RS
1603 int *priority = (int *) xmalloc (sizeof (int) * argc);
1604 int to = 1;
956e3c7e 1605 int incoming_used = 1;
081bef73
RS
1606 int from;
1607 int i;
1608
1609 /* Categorize all the options,
1610 and figure out which argv elts are option arguments. */
1611 for (from = 1; from < argc; from++)
1612 {
1613 options[from] = -1;
fcdeb5d9 1614 priority[from] = 0;
081bef73
RS
1615 if (argv[from][0] == '-')
1616 {
1617 int match, thislen;
1618 char *equals;
1619
c96f26f4
RS
1620 /* If we have found "--", don't consider
1621 any more arguments as options. */
249443b6 1622 if (argv[from][1] == '-' && argv[from][2] == 0)
c96f26f4
RS
1623 {
1624 /* Leave the "--", and everything following it, at the end. */
1625 for (; from < argc; from++)
1626 {
1627 priority[from] = -100;
1628 options[from] = -1;
1629 }
1630 break;
1631 }
1632
081bef73
RS
1633 /* Look for a match with a known old-fashioned option. */
1634 for (i = 0; i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
1635 if (!strcmp (argv[from], standard_args[i].name))
1636 {
1637 options[from] = standard_args[i].nargs;
1638 priority[from] = standard_args[i].priority;
fd76ec52
RS
1639 if (from + standard_args[i].nargs >= argc)
1640 fatal ("Option `%s' requires an argument\n", argv[from]);
081bef73
RS
1641 from += standard_args[i].nargs;
1642 goto done;
1643 }
1644
1645 /* Look for a match with a known long option.
1646 MATCH is -1 if no match so far, -2 if two or more matches so far,
1647 >= 0 (the table index of the match) if just one match so far. */
1648 if (argv[from][1] == '-')
1649 {
1650 match = -1;
1651 thislen = strlen (argv[from]);
1652 equals = index (argv[from], '=');
1653 if (equals != 0)
1654 thislen = equals - argv[from];
1655
f609ef57
KH
1656 for (i = 0;
1657 i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
1658 if (standard_args[i].longname
1659 && !strncmp (argv[from], standard_args[i].longname,
1660 thislen))
081bef73
RS
1661 {
1662 if (match == -1)
1663 match = i;
1664 else
1665 match = -2;
1666 }
1667
1668 /* If we found exactly one match, use that. */
1669 if (match >= 0)
1670 {
1671 options[from] = standard_args[match].nargs;
1672 priority[from] = standard_args[match].priority;
1673 /* If --OPTION=VALUE syntax is used,
1674 this option uses just one argv element. */
1675 if (equals != 0)
1676 options[from] = 0;
fd76ec52
RS
1677 if (from + options[from] >= argc)
1678 fatal ("Option `%s' requires an argument\n", argv[from]);
081bef73
RS
1679 from += options[from];
1680 }
1681 }
1682 done: ;
1683 }
1684 }
1685
1686 /* Copy the arguments, in order of decreasing priority, to NEW. */
1687 new[0] = argv[0];
956e3c7e 1688 while (incoming_used < argc)
081bef73
RS
1689 {
1690 int best = -1;
2c70c992 1691 int best_priority = -9999;
081bef73
RS
1692
1693 /* Find the highest priority remaining option.
1694 If several have equal priority, take the first of them. */
1695 for (from = 1; from < argc; from++)
1696 {
1697 if (argv[from] != 0 && priority[from] > best_priority)
1698 {
1699 best_priority = priority[from];
1700 best = from;
1701 }
1702 /* Skip option arguments--they are tied to the options. */
1703 if (options[from] > 0)
1704 from += options[from];
1705 }
1706
1707 if (best < 0)
1708 abort ();
1709
956e3c7e
RS
1710 /* Copy the highest priority remaining option, with its args, to NEW.
1711 Unless it is a duplicate of the previous one. */
1712 if (! (options[best] == 0
1713 && ! strcmp (new[to - 1], argv[best])))
1714 {
1715 new[to++] = argv[best];
1716 for (i = 0; i < options[best]; i++)
1717 new[to++] = argv[best + i + 1];
1718 }
1719
1720 incoming_used += 1 + (options[best] > 0 ? options[best] : 0);
081bef73
RS
1721
1722 /* Clear out this option in ARGV. */
1723 argv[best] = 0;
1724 for (i = 0; i < options[best]; i++)
1725 argv[best + i + 1] = 0;
1726 }
1727
81b7af72
RS
1728 /* If duplicate options were deleted, fill up extra space with null ptrs. */
1729 while (to < argc)
1730 new[to++] = 0;
1731
6dad9359 1732 bcopy (new, argv, sizeof (char *) * argc);
0bf591da
RS
1733
1734 free (options);
1735 free (new);
1736 free (priority);
081bef73
RS
1737}
1738\f
f927c5ae 1739DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P",
edc8ae07 1740 "Exit the Emacs job and kill it.\n\
f927c5ae
JB
1741If ARG is an integer, return ARG as the exit program code.\n\
1742If ARG is a string, stuff it as keyboard input.\n\n\
1743The value of `kill-emacs-hook', if not void,\n\
1744is a list of functions (of no args),\n\
1745all of which are called before Emacs is actually killed.")
1746 (arg)
1747 Lisp_Object arg;
1748{
f927c5ae
JB
1749 struct gcpro gcpro1;
1750
1751 GCPRO1 (arg);
1752
1753 if (feof (stdin))
1754 arg = Qt;
1755
2447c626 1756 if (!NILP (Vrun_hooks) && !noninteractive)
f927c5ae
JB
1757 call1 (Vrun_hooks, intern ("kill-emacs-hook"));
1758
f927c5ae
JB
1759 UNGCPRO;
1760
1761/* Is it really necessary to do this deassign
1762 when we are going to exit anyway? */
1763/* #ifdef VMS
1764 stop_vms_input ();
1765 #endif */
40be253a 1766
d0068e25 1767 shut_down_emacs (0, 0, STRINGP (arg) ? arg : Qnil);
40be253a 1768
58545838
KH
1769 /* If we have an auto-save list file,
1770 kill it because we are exiting Emacs deliberately (not crashing).
1771 Do it after shut_down_emacs, which does an auto-save. */
1772 if (STRINGP (Vauto_save_list_file_name))
1773 unlink (XSTRING (Vauto_save_list_file_name)->data);
1774
55ccc0b3 1775 exit (INTEGERP (arg) ? XINT (arg)
f927c5ae
JB
1776#ifdef VMS
1777 : 1
1778#else
1779 : 0
1780#endif
1781 );
1782 /* NOTREACHED */
1783}
40be253a
JB
1784
1785
1786/* Perform an orderly shutdown of Emacs. Autosave any modified
1787 buffers, kill any child processes, clean up the terminal modes (if
1788 we're in the foreground), and other stuff like that. Don't perform
1789 any redisplay; this may be called when Emacs is shutting down in
1790 the background, or after its X connection has died.
1791
1792 If SIG is a signal number, print a message for it.
1793
1794 This is called by fatal signal handlers, X protocol error handlers,
1795 and Fkill_emacs. */
f7ab4e3d 1796
40be253a 1797void
f7ab4e3d 1798shut_down_emacs (sig, no_x, stuff)
41423a80 1799 int sig, no_x;
f7ab4e3d 1800 Lisp_Object stuff;
40be253a 1801{
829d872b
RS
1802 /* Prevent running of hooks from now on. */
1803 Vrun_hooks = Qnil;
1804
40be253a
JB
1805 /* If we are controlling the terminal, reset terminal modes */
1806#ifdef EMACS_HAVE_TTY_PGRP
1807 {
d04d81d2
RS
1808 int pgrp = EMACS_GETPGRP (0);
1809
40be253a
JB
1810 int tpgrp;
1811 if (EMACS_GET_TTY_PGRP (0, &tpgrp) != -1
5a570e37 1812 && tpgrp == pgrp)
40be253a
JB
1813 {
1814 fflush (stdout);
1815 reset_sys_modes ();
1816 if (sig && sig != SIGTERM)
1817 fprintf (stderr, "Fatal error (%d).", sig);
1818 }
1819 }
1820#else
1821 fflush (stdout);
1822 reset_sys_modes ();
1823#endif
1824
f7ab4e3d
RS
1825 stuff_buffered_input (stuff);
1826
40be253a
JB
1827 kill_buffer_processes (Qnil);
1828 Fdo_auto_save (Qt, Qnil);
1829
1830#ifdef CLASH_DETECTION
1831 unlock_all_files ();
1832#endif
1833
1834#ifdef VMS
1835 kill_vms_processes ();
1836#endif
1837
5e7f8733 1838#if 0 /* This triggers a bug in XCloseDisplay and is not needed. */
41423a80 1839#ifdef HAVE_X_WINDOWS
f7511647
RS
1840 /* It's not safe to call intern here. Maybe we are crashing. */
1841 if (!noninteractive && SYMBOLP (Vwindow_system)
1842 && XSYMBOL (Vwindow_system)->name->size == 1
1843 && XSYMBOL (Vwindow_system)->name->data[0] == 'x'
1844 && ! no_x)
41423a80
RS
1845 Fx_close_current_connection ();
1846#endif /* HAVE_X_WINDOWS */
5e7f8733 1847#endif
41423a80 1848
40be253a
JB
1849#ifdef SIGIO
1850 /* There is a tendency for a SIGIO signal to arrive within exit,
1851 and cause a SIGHUP because the input descriptor is already closed. */
1852 unrequest_sigio ();
1853 signal (SIGIO, SIG_IGN);
1854#endif
41f339d4
RS
1855
1856#ifdef WINDOWSNT
1857 term_ntproc ();
1858#endif
d546e578 1859
90d920b6 1860 check_glyph_memory ();
189437a7 1861 check_message_stack ();
90d920b6 1862
d546e578
EZ
1863#ifdef MSDOS
1864 dos_cleanup ();
1865#endif
40be253a
JB
1866}
1867
1868
f927c5ae
JB
1869\f
1870#ifndef CANNOT_DUMP
f927c5ae
JB
1871
1872#ifdef HAVE_SHM
1873
1874DEFUN ("dump-emacs-data", Fdump_emacs_data, Sdump_emacs_data, 1, 1, 0,
1875 "Dump current state of Emacs into data file FILENAME.\n\
1876This function exists on systems that use HAVE_SHM.")
c9aae259
EN
1877 (filename)
1878 Lisp_Object filename;
f927c5ae 1879{
55697f5b 1880 extern char my_edata[];
f927c5ae 1881 Lisp_Object tem;
f927c5ae 1882
c9aae259
EN
1883 CHECK_STRING (filename, 0);
1884 filename = Fexpand_file_name (filename, Qnil);
f927c5ae
JB
1885
1886 tem = Vpurify_flag;
1887 Vpurify_flag = Qnil;
1888
1889 fflush (stdout);
1890 /* Tell malloc where start of impure now is */
1891 /* Also arrange for warnings when nearly out of space. */
1892#ifndef SYSTEM_MALLOC
1090a161 1893 memory_warnings (my_edata, malloc_warning);
f927c5ae 1894#endif
c9aae259 1895 map_out_data (XSTRING (filename)->data);
f927c5ae
JB
1896
1897 Vpurify_flag = tem;
1898
1899 return Qnil;
1900}
1901
1902#else /* not HAVE_SHM */
1903
1904DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0,
1905 "Dump current state of Emacs into executable file FILENAME.\n\
1906Take symbols from SYMFILE (presumably the file you executed to run Emacs).\n\
1907This is used in the file `loadup.el' when building Emacs.\n\
1908\n\
87a98b1a 1909You must run Emacs in batch mode in order to dump it.")
c9aae259
EN
1910 (filename, symfile)
1911 Lisp_Object filename, symfile;
f927c5ae 1912{
55697f5b 1913 extern char my_edata[];
f927c5ae 1914 Lisp_Object tem;
1b7ddf4f
RS
1915 Lisp_Object symbol;
1916 int count = specpdl_ptr - specpdl;
f927c5ae 1917
87a98b1a
RS
1918 if (! noninteractive)
1919 error ("Dumping Emacs works only in batch mode");
1920
1b7ddf4f
RS
1921 /* Bind `command-line-processed' to nil before dumping,
1922 so that the dumped Emacs will process its command line
1923 and set up to work with X windows if appropriate. */
1924 symbol = intern ("command-line-process");
1925 specbind (symbol, Qnil);
1926
c9aae259
EN
1927 CHECK_STRING (filename, 0);
1928 filename = Fexpand_file_name (filename, Qnil);
1929 if (!NILP (symfile))
f927c5ae 1930 {
c9aae259
EN
1931 CHECK_STRING (symfile, 0);
1932 if (XSTRING (symfile)->size)
1933 symfile = Fexpand_file_name (symfile, Qnil);
f927c5ae
JB
1934 }
1935
1936 tem = Vpurify_flag;
1937 Vpurify_flag = Qnil;
1938
0269dedb
RS
1939#ifdef HAVE_TZSET
1940 set_time_zone_rule (dump_tz);
1941#ifndef LOCALTIME_CACHE
1942 /* Force a tz reload, since set_time_zone_rule doesn't. */
1943 tzset ();
1944#endif
1945#endif
1946
f927c5ae
JB
1947 fflush (stdout);
1948#ifdef VMS
c9aae259 1949 mapout_data (XSTRING (filename)->data);
f927c5ae
JB
1950#else
1951 /* Tell malloc where start of impure now is */
1952 /* Also arrange for warnings when nearly out of space. */
1953#ifndef SYSTEM_MALLOC
cc5f52cb
RS
1954#ifndef WINDOWSNT
1955 /* On Windows, this was done before dumping, and that once suffices.
1956 Meanwhile, my_edata is not valid on Windows. */
cb37cf78 1957 memory_warnings (my_edata, malloc_warning);
cc5f52cb 1958#endif /* not WINDOWSNT */
15aaf1b5
RS
1959#endif
1960#ifdef DOUG_LEA_MALLOC
1961 malloc_state_ptr = malloc_get_state ();
f927c5ae 1962#endif
c9aae259
EN
1963 unexec (XSTRING (filename)->data,
1964 !NILP (symfile) ? XSTRING (symfile)->data : 0, my_edata, 0, 0);
15aaf1b5
RS
1965#ifdef DOUG_LEA_MALLOC
1966 free (malloc_state_ptr);
1967#endif
f927c5ae
JB
1968#endif /* not VMS */
1969
1970 Vpurify_flag = tem;
1971
1b7ddf4f 1972 return unbind_to (count, Qnil);
f927c5ae
JB
1973}
1974
1975#endif /* not HAVE_SHM */
1976
1977#endif /* not CANNOT_DUMP */
1978\f
68c45bf0
PE
1979#if HAVE_SETLOCALE
1980/* Recover from setlocale (LC_ALL, ""). */
1981void
1982fixup_locale ()
1983{
68c45bf0
PE
1984 /* The Emacs Lisp reader needs LC_NUMERIC to be "C",
1985 so that numbers are read and printed properly for Emacs Lisp. */
1986 setlocale (LC_NUMERIC, "C");
68c45bf0
PE
1987}
1988
0c8559bb
PE
1989/* Set system locale CATEGORY, with previous locale *PLOCALE, to
1990 DESIRED_LOCALE. */
68c45bf0
PE
1991static void
1992synchronize_locale (category, plocale, desired_locale)
1993 int category;
1994 Lisp_Object *plocale;
1995 Lisp_Object desired_locale;
1996{
0c8559bb
PE
1997 if (! EQ (*plocale, desired_locale))
1998 {
1999 *plocale = desired_locale;
2000 setlocale (category, (STRINGP (desired_locale)
59c65f1e 2001 ? (char *)(XSTRING (desired_locale)->data)
0c8559bb
PE
2002 : ""));
2003 }
68c45bf0
PE
2004}
2005
ca9c0567 2006/* Set system time locale to match Vsystem_time_locale, if possible. */
68c45bf0 2007void
ca9c0567 2008synchronize_system_time_locale ()
68c45bf0 2009{
ca9c0567
PE
2010 synchronize_locale (LC_TIME, &Vprevious_system_time_locale,
2011 Vsystem_time_locale);
68c45bf0
PE
2012}
2013
ca9c0567
PE
2014/* Set system messages locale to match Vsystem_messages_locale, if
2015 possible. */
68c45bf0 2016void
ca9c0567 2017synchronize_system_messages_locale ()
68c45bf0
PE
2018{
2019#ifdef LC_MESSAGES
ca9c0567
PE
2020 synchronize_locale (LC_MESSAGES, &Vprevious_system_messages_locale,
2021 Vsystem_messages_locale);
68c45bf0
PE
2022#endif
2023}
2024#endif /* HAVE_SETLOCALE */
2025\f
4b163808 2026#ifndef SEPCHAR
f927c5ae
JB
2027#define SEPCHAR ':'
2028#endif
2029
2030Lisp_Object
2031decode_env_path (evarname, defalt)
2032 char *evarname, *defalt;
2033{
2034 register char *path, *p;
213d0b1f 2035 Lisp_Object lpath, element, tem;
f927c5ae 2036
2447c626
JB
2037 /* It's okay to use getenv here, because this function is only used
2038 to initialize variables when Emacs starts up, and isn't called
2039 after that. */
e065a56e
JB
2040 if (evarname != 0)
2041 path = (char *) getenv (evarname);
2042 else
2043 path = 0;
f927c5ae
JB
2044 if (!path)
2045 path = defalt;
6a30e6d6
RS
2046#ifdef DOS_NT
2047 /* Ensure values from the environment use the proper directory separator. */
2048 if (path)
2049 {
2050 p = alloca (strlen (path) + 1);
2051 strcpy (p, path);
2052 path = p;
2053
2054 if ('/' == DIRECTORY_SEP)
2055 dostounix_filename (path);
2056 else
2057 unixtodos_filename (path);
2058 }
2059#endif
f927c5ae
JB
2060 lpath = Qnil;
2061 while (1)
2062 {
2063 p = index (path, SEPCHAR);
2064 if (!p) p = path + strlen (path);
213d0b1f
RS
2065 element = (p - path ? make_string (path, p - path)
2066 : build_string ("."));
2067
2068 /* Add /: to the front of the name
2069 if it would otherwise be treated as magic. */
2070 tem = Ffind_file_name_handler (element, Qt);
2071 if (! NILP (tem))
2072 element = concat2 (build_string ("/:"), element);
2073
2074 lpath = Fcons (element, lpath);
f927c5ae
JB
2075 if (*p)
2076 path = p + 1;
2077 else
2078 break;
2079 }
2080 return Fnreverse (lpath);
2081}
2082
dfcf069d 2083void
f927c5ae
JB
2084syms_of_emacs ()
2085{
213d0b1f
RS
2086 Qfile_name_handler_alist = intern ("file-name-handler-alist");
2087 staticpro (&Qfile_name_handler_alist);
2088
83591e66 2089#ifndef CANNOT_DUMP
f927c5ae
JB
2090#ifdef HAVE_SHM
2091 defsubr (&Sdump_emacs_data);
2092#else
2093 defsubr (&Sdump_emacs);
83591e66 2094#endif
f927c5ae
JB
2095#endif
2096
2097 defsubr (&Skill_emacs);
2098
59653951 2099 defsubr (&Sinvocation_name);
ace40a69 2100 defsubr (&Sinvocation_directory);
59653951 2101
f927c5ae
JB
2102 DEFVAR_LISP ("command-line-args", &Vcommand_line_args,
2103 "Args passed by shell to Emacs, as a list of strings.");
2104
2105 DEFVAR_LISP ("system-type", &Vsystem_type,
2106 "Value is symbol indicating type of operating system you are using.");
2107 Vsystem_type = intern (SYSTEM_TYPE);
2108
271c7b7c
RS
2109 DEFVAR_LISP ("system-configuration", &Vsystem_configuration,
2110 "Value is string indicating configuration Emacs was built for.");
f7511647 2111 Vsystem_configuration = build_string (EMACS_CONFIGURATION);
271c7b7c 2112
f0fc0b1a
KH
2113 DEFVAR_LISP ("system-configuration-options", &Vsystem_configuration_options,
2114 "String containing the configuration options Emacs was built with.");
2115 Vsystem_configuration_options = build_string (EMACS_CONFIG_OPTIONS);
2116
f927c5ae
JB
2117 DEFVAR_BOOL ("noninteractive", &noninteractive1,
2118 "Non-nil means Emacs is running without interactive terminal.");
e5d77022 2119
e5d77022 2120 DEFVAR_LISP ("kill-emacs-hook", &Vkill_emacs_hook,
edc8ae07
JB
2121 "Hook to be run whenever kill-emacs is called.\n\
2122Since kill-emacs may be invoked when the terminal is disconnected (or\n\
2123in other similar situations), functions placed on this hook should not\n\
9f232a5d
RS
2124expect to be able to interact with the user. To ask for confirmation,\n\
2125see `kill-emacs-query-functions' instead.");
edc8ae07 2126 Vkill_emacs_hook = Qnil;
3005da00 2127
7317d9e8
RS
2128#ifdef SIGUSR1
2129 DEFVAR_LISP ("signal-USR1-hook", &Vsignal_USR1_hook,
3e75bb9e 2130 "Hook to be run whenever emacs receives a USR1 signal");
7317d9e8
RS
2131 Vsignal_USR1_hook = Qnil;
2132#ifdef SIGUSR2
2133 DEFVAR_LISP ("signal-USR2-hook", &Vsignal_USR2_hook,
3e75bb9e 2134 "Hook to be run whenever emacs receives a USR2 signal");
7317d9e8
RS
2135 Vsignal_USR2_hook = Qnil;
2136#endif
2137#endif
2138
2139
3005da00
RS
2140 DEFVAR_INT ("emacs-priority", &emacs_priority,
2141 "Priority for Emacs to run at.\n\
2142This value is effective only if set before Emacs is dumped,\n\
2143and only if the Emacs executable is installed with setuid to permit\n\
621ecf99 2144it to change priority. (Emacs sets its uid back to the real uid.)\n\
a422068f 2145Currently, you need to define SET_EMACS_PRIORITY in `config.h'\n\
e7a9e1c3
RS
2146before you compile Emacs, to enable the code for this feature.");
2147 emacs_priority = 0;
074a066b
GV
2148
2149 DEFVAR_LISP ("path-separator", &Vpath_separator,
2150 "The directory separator in search paths, as a string.");
2151 {
2152 char c = SEPCHAR;
2153 Vpath_separator = make_string (&c, 1);
2154 }
59653951 2155
f67de86f
RS
2156 DEFVAR_LISP ("invocation-name", &Vinvocation_name,
2157 "The program name that was used to run Emacs.\n\
2158Any directory names are omitted.");
2159
2160 DEFVAR_LISP ("invocation-directory", &Vinvocation_directory,
2161 "The directory in which the Emacs executable was found, to run it.\n\
2162The value is nil if that directory's name is not known.");
2163
2164 DEFVAR_LISP ("installation-directory", &Vinstallation_directory,
2165 "A directory within which to look for the `lib-src' and `etc' directories.\n\
2166This is non-nil when we can't find those directories in their standard\n\
2167installed locations, but we can find them\n\
2168near where the Emacs executable was found.");
07f4d123 2169 Vinstallation_directory = Qnil;
68c45bf0 2170
ca9c0567 2171 DEFVAR_LISP ("system-messages-locale", &Vsystem_messages_locale,
68c45bf0 2172 "System locale for messages.");
ca9c0567 2173 Vsystem_messages_locale = Qnil;
68c45bf0 2174
ca9c0567
PE
2175 DEFVAR_LISP ("previous-system-messages-locale",
2176 &Vprevious_system_messages_locale,
68c45bf0 2177 "Most recently used system locale for messages.");
ca9c0567 2178 Vprevious_system_messages_locale = Qnil;
68c45bf0 2179
ca9c0567 2180 DEFVAR_LISP ("system-time-locale", &Vsystem_time_locale,
68c45bf0 2181 "System locale for time.");
ca9c0567 2182 Vsystem_time_locale = Qnil;
68c45bf0 2183
ca9c0567 2184 DEFVAR_LISP ("previous-system-time-locale", &Vprevious_system_time_locale,
68c45bf0 2185 "Most recently used system locale for time.");
ca9c0567 2186 Vprevious_system_time_locale = Qnil;
f927c5ae 2187}