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