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