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