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