(vendor-key-syms): Set this variable.
[bpt/emacs.git] / src / emacs.c
CommitLineData
f927c5ae 1/* Fully extensible Emacs, running on Unix, intended for GNU.
c6c5df7f 2 Copyright (C) 1985, 1986, 1987, 1993 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
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21#include <signal.h>
22#include <errno.h>
23
18160b98 24#include <config.h>
f927c5ae
JB
25#include <stdio.h>
26
27#include <sys/types.h>
28#include <sys/file.h>
29
30#ifdef VMS
31#include <ssdef.h>
32#endif
33
f927c5ae
JB
34#ifdef BSD
35#include <sys/ioctl.h>
36#endif
37
38#ifdef APOLLO
39#ifndef APOLLO_SR10
40#include <default_acl.h>
41#endif
42#endif
43
f927c5ae
JB
44#include "lisp.h"
45#include "commands.h"
bef79ee4 46#include "intervals.h"
f927c5ae 47
edc8ae07 48#include "systty.h"
8090eb09 49#include "syssignal.h"
6c362a8b 50#include "process.h"
a41f8bed 51
f927c5ae
JB
52#ifndef O_RDWR
53#define O_RDWR 2
54#endif
55
f927c5ae
JB
56/* Command line args from shell, as list of strings */
57Lisp_Object Vcommand_line_args;
58
59653951
JB
59/* The name under which Emacs was invoked, with any leading directory
60 names discarded. */
61Lisp_Object Vinvocation_name;
62
ace40a69
RS
63/* The directory name from which Emacs was invoked. */
64Lisp_Object Vinvocation_directory;
65
e5d77022
JB
66/* Hook run by `kill-emacs' before it does really anything. */
67Lisp_Object Vkill_emacs_hook;
68
f927c5ae
JB
69/* Set nonzero after Emacs has started up the first time.
70 Prevents reinitialization of the Lisp world and keymaps
71 on subsequent starts. */
72int initialized;
73
271c7b7c 74/* Variable whose value is symbol giving operating system type. */
f927c5ae 75Lisp_Object Vsystem_type;
271c7b7c
RS
76
77/* Variable whose value is string giving configuration built for. */
78Lisp_Object Vsystem_configuration;
f927c5ae
JB
79
80/* If non-zero, emacs should not attempt to use an window-specific code,
81 but instead should use the virtual terminal under which it was started */
82int inhibit_window_system;
83
5aa7f46a
JB
84/* If nonzero, set Emacs to run at this priority. This is also used
85 in child_setup and sys_suspend to make sure subshells run at normal
86 priority; Those functions have their own extern declaration. */
3005da00
RS
87int emacs_priority;
88
9ae8f997
JB
89#ifdef BSD
90/* See sysdep.c. */
91extern int inherited_pgroup;
92#endif
93
f927c5ae
JB
94#ifdef HAVE_X_WINDOWS
95/* If non-zero, -d was specified, meaning we're using some window system. */
96int display_arg;
97#endif
98
99/* An address near the bottom of the stack.
100 Tells GC how to save a copy of the stack. */
101char *stack_bottom;
102
103#ifdef HAVE_X_WINDOWS
104extern Lisp_Object Vwindow_system;
105#endif /* HAVE_X_WINDOWS */
106
107#ifdef USG_SHARED_LIBRARIES
108/* If nonzero, this is the place to put the end of the writable segment
109 at startup. */
110
111unsigned int bss_end = 0;
112#endif
113
114/* Nonzero means running Emacs without interactive terminal. */
115
116int noninteractive;
117
118/* Value of Lisp variable `noninteractive'.
119 Normally same as C variable `noninteractive'
120 but nothing terrible happens if user sets this one. */
121
122int noninteractive1;
123\f
124/* Signal code for the fatal signal that was received */
125int fatal_error_code;
126
127/* Nonzero if handling a fatal error already */
128int fatal_error_in_progress;
129
130/* Handle bus errors, illegal instruction, etc. */
2447c626 131SIGTYPE
f927c5ae
JB
132fatal_error_signal (sig)
133 int sig;
134{
f927c5ae
JB
135 fatal_error_code = sig;
136 signal (sig, SIG_DFL);
137
138 /* If fatal error occurs in code below, avoid infinite recursion. */
8090eb09
JB
139 if (! fatal_error_in_progress)
140 {
141 fatal_error_in_progress = 1;
f927c5ae 142
f7ab4e3d 143 shut_down_emacs (sig, 0, Qnil);
8090eb09 144 }
f927c5ae
JB
145
146#ifdef VMS
f927c5ae
JB
147 LIB$STOP (SS$_ABORT);
148#else
8090eb09
JB
149 /* Signal the same code; this time it will really be fatal.
150 Remember that since we're in a signal handler, the signal we're
151 going to send is probably blocked, so we have to unblock it if we
152 want to really receive it. */
29b89fe0 153#ifndef MSDOS
a90538cb 154 sigunblock (sigmask (fatal_error_code));
29b89fe0 155#endif
f927c5ae
JB
156 kill (getpid (), fatal_error_code);
157#endif /* not VMS */
158}
271c7b7c
RS
159
160#ifdef SIGDANGER
161
162/* Handle bus errors, illegal instruction, etc. */
163SIGTYPE
164memory_warning_signal (sig)
165 int sig;
166{
167 signal (sig, memory_warning_signal);
168
169 malloc_warning ("Operating system warns that virtual memory is running low.\n");
170}
171#endif
f927c5ae
JB
172\f
173/* Code for dealing with Lisp access to the Unix command line */
174
175static
176init_cmdargs (argc, argv, skip_args)
177 int argc;
178 char **argv;
179 int skip_args;
180{
181 register int i;
182
cb421be8 183 Vinvocation_name = Ffile_name_nondirectory (build_string (argv[0]));
ace40a69
RS
184 Vinvocation_directory = Ffile_name_directory (build_string (argv[0]));
185 /* If we got no directory in argv[0], search PATH to find where
186 Emacs actually came from. */
187 if (NILP (Vinvocation_directory))
188 {
189 Lisp_Object found;
190 int yes = openp (Vexec_path, Vinvocation_name,
6c362a8b 191 EXEC_SUFFIXES, &found, 1);
e443f843 192 if (yes == 1)
ace40a69
RS
193 Vinvocation_directory = Ffile_name_directory (found);
194 }
59653951 195
f927c5ae
JB
196 Vcommand_line_args = Qnil;
197
198 for (i = argc - 1; i >= 0; i--)
199 {
200 if (i == 0 || i > skip_args)
201 Vcommand_line_args
202 = Fcons (build_string (argv[i]), Vcommand_line_args);
203 }
204}
59653951
JB
205
206DEFUN ("invocation-name", Finvocation_name, Sinvocation_name, 0, 0, 0,
207 "Return the program name that was used to run Emacs.\n\
208Any directory names are omitted.")
209 ()
210{
211 return Fcopy_sequence (Vinvocation_name);
212}
213
ace40a69
RS
214DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory,
215 0, 0, 0,
216 "Return the directory name in which the Emacs executable was located")
217 ()
218{
219 return Fcopy_sequence (Vinvocation_directory);
220}
221
f927c5ae
JB
222\f
223#ifdef VMS
224#ifdef LINK_CRTL_SHARE
225#ifdef SHAREABLE_LIB_BUG
226extern noshare char **environ;
227#endif /* SHAREABLE_LIB_BUG */
228#endif /* LINK_CRTL_SHARE */
229#endif /* VMS */
230
a90538cb 231#ifndef ORDINARY_LINK
efd241cc
RS
232/* We don't include crtbegin.o and crtend.o in the link,
233 so these functions and variables might be missed.
234 Provide dummy definitions to avoid error.
235 (We don't have any real constructors or destructors.) */
236#ifdef __GNUC__
c83a7064 237__do_global_ctors ()
efd241cc 238{}
c83a7064
RS
239__do_global_ctors_aux ()
240{}
33143604
RS
241__do_global_dtors ()
242{}
64c1864a
RS
243/* Linux has a bug in its library; avoid an error. */
244#ifndef LINUX
c83a7064 245char * __CTOR_LIST__[2] = { (char *) (-1), 0 };
64c1864a 246#endif
c83a7064
RS
247char * __DTOR_LIST__[2] = { (char *) (-1), 0 };
248__main ()
efd241cc 249{}
efd241cc 250#endif /* __GNUC__ */
a90538cb 251#endif /* ORDINARY_LINK */
efd241cc 252
f927c5ae
JB
253/* ARGSUSED */
254main (argc, argv, envp)
255 int argc;
256 char **argv;
257 char **envp;
258{
259 char stack_bottom_variable;
260 int skip_args = 0;
261 extern int errno;
262 extern sys_nerr;
263 extern char *sys_errlist[];
264 extern void malloc_warning ();
265
266/* Map in shared memory, if we are using that. */
267#ifdef HAVE_SHM
268 if (argc > 1 && !strcmp (argv[1], "-nl"))
269 {
270 map_in_data (0);
271 /* The shared memory was just restored, which clobbered this. */
272 skip_args = 1;
273 }
274 else
275 {
276 map_in_data (1);
277 /* The shared memory was just restored, which clobbered this. */
278 skip_args = 0;
279 }
280#endif
281
19a36ec6 282#ifdef NeXT
4b163808 283 extern int malloc_cookie;
19a36ec6
RS
284
285 /* This helps out unexnext.c. */
286 if (initialized)
287 if (malloc_jumpstart (malloc_cookie) != 0)
288 printf ("malloc jumpstart failed!\n");
289#endif /* NeXT */
290
f927c5ae 291#ifdef HAVE_X_WINDOWS
fb8e9847
JB
292 /* Stupid kludge to catch command-line display spec. We can't
293 handle this argument entirely in window system dependent code
294 because we don't even know which window system dependent code
295 to run until we've recognized this argument. */
f927c5ae
JB
296 {
297 int i;
298
299 for (i = 1; (i < argc && ! display_arg); i++)
92381c7c 300 if (!strcmp (argv[i], "-d") || !strcmp (argv[i], "-display"))
f927c5ae
JB
301 display_arg = 1;
302 }
303#endif
304
305#ifdef VMS
306 /* If -map specified, map the data file in */
307 if (argc > 2 && ! strcmp (argv[1], "-map"))
308 {
309 skip_args = 2;
310 mapin_data (argv[2]);
311 }
312
313#ifdef LINK_CRTL_SHARE
314#ifdef SHAREABLE_LIB_BUG
315 /* Bletcherous shared libraries! */
316 if (!stdin)
317 stdin = fdopen (0, "r");
318 if (!stdout)
319 stdout = fdopen (1, "w");
320 if (!stderr)
321 stderr = fdopen (2, "w");
322 if (!environ)
323 environ = envp;
324#endif /* SHAREABLE_LIB_BUG */
325#endif /* LINK_CRTL_SHARE */
326#endif /* VMS */
327
328 /* Record (approximately) where the stack begins. */
329 stack_bottom = &stack_bottom_variable;
330
331#ifdef RUN_TIME_REMAP
332 if (initialized)
333 run_time_remap (argv[0]);
334#endif
335
336#ifdef USG_SHARED_LIBRARIES
337 if (bss_end)
338 brk (bss_end);
339#endif
340
341 clearerr (stdin);
9ae8f997 342
f927c5ae 343#ifdef BSD
e8589b11
RS
344 if (initialized)
345 {
346 inherited_pgroup = EMACS_GETPGRP (0);
347 setpgrp (0, getpid ());
348 }
f927c5ae
JB
349#endif
350
9ae8f997 351
f927c5ae
JB
352#ifdef APOLLO
353#ifndef APOLLO_SR10
354 /* If USE_DOMAIN_ACLS environment variable exists,
355 use ACLs rather than UNIX modes. */
356 if (egetenv ("USE_DOMAIN_ACLS"))
357 default_acl (USE_DEFACL);
358#endif
359#endif /* APOLLO */
360
361#ifndef SYSTEM_MALLOC
362 if (! initialized)
9ac0d9e0
JB
363 {
364 /* Arrange to get warning messages as memory fills up. */
365 memory_warnings (0, malloc_warning);
366
367 /* Arrange to disable interrupt input while malloc and friends are
368 running. */
369 uninterrupt_malloc ();
370 }
f927c5ae
JB
371#endif /* not SYSTEM_MALLOC */
372
29b89fe0
RS
373#ifdef MSDOS
374 /* We do all file input/output as binary files. When we need to translate
375 newlines, we do that manually. */
376 _fmode = O_BINARY;
377 (stdin)->_flag &= ~_IOTEXT;
378 (stdout)->_flag &= ~_IOTEXT;
379 (stderr)->_flag &= ~_IOTEXT;
380#endif /* MSDOS */
381
3005da00
RS
382#ifdef PRIO_PROCESS
383 if (emacs_priority)
5aa7f46a 384 nice (emacs_priority);
f927c5ae 385 setuid (getuid ());
3005da00 386#endif /* PRIO_PROCESS */
f927c5ae 387
f927c5ae
JB
388 inhibit_window_system = 0;
389
4fc0b45b 390 /* Handle the -t switch, which specifies filename to use as terminal */
f927c5ae
JB
391 if (skip_args + 2 < argc && !strcmp (argv[skip_args + 1], "-t"))
392 {
393 int result;
394 skip_args += 2;
395 close (0);
396 close (1);
397 result = open (argv[skip_args], O_RDWR, 2 );
398 if (result < 0)
399 {
400 char *errstring;
401
402 if (errno >= 0 && errno < sys_nerr)
403 errstring = sys_errlist[errno];
404 else
405 errstring = "undocumented error code";
406 fprintf (stderr, "emacs: %s: %s\n", argv[skip_args], errstring);
407 exit (1);
408 }
409 dup (0);
410 if (! isatty (0))
411 {
412 fprintf (stderr, "emacs: %s: not a tty\n", argv[skip_args]);
413 exit (1);
414 }
415 fprintf (stderr, "Using %s\n", argv[skip_args]);
416#ifdef HAVE_X_WINDOWS
417 inhibit_window_system = 1; /* -t => -nw */
418#endif
419 }
420
421 if (skip_args + 1 < argc
422 && (!strcmp (argv[skip_args + 1], "-nw")))
423 {
424 skip_args += 1;
425 inhibit_window_system = 1;
426 }
427
428/* Handle the -batch switch, which means don't do interactive display. */
429 noninteractive = 0;
430 if (skip_args + 1 < argc && !strcmp (argv[skip_args + 1], "-batch"))
431 {
432 skip_args += 1;
433 noninteractive = 1;
434 }
435
fb8e9847
JB
436#ifdef POSIX_SIGNALS
437 init_signals ();
438#endif
439
f927c5ae
JB
440 if (
441#ifndef CANNOT_DUMP
442 ! noninteractive || initialized
443#else
444 1
445#endif
446 )
447 {
448 /* Don't catch these signals in batch mode if not initialized.
449 On some machines, this sets static data that would make
450 signal fail to work right when the dumped Emacs is run. */
451 signal (SIGHUP, fatal_error_signal);
452 signal (SIGQUIT, fatal_error_signal);
453 signal (SIGILL, fatal_error_signal);
454 signal (SIGTRAP, fatal_error_signal);
a90538cb
JB
455#ifdef SIGIOT
456 /* This is missing on some systems - OS/2, for example. */
f927c5ae 457 signal (SIGIOT, fatal_error_signal);
a90538cb 458#endif
f927c5ae
JB
459#ifdef SIGEMT
460 signal (SIGEMT, fatal_error_signal);
461#endif
462 signal (SIGFPE, fatal_error_signal);
00eaaa32 463#ifdef SIGBUS
f927c5ae 464 signal (SIGBUS, fatal_error_signal);
00eaaa32 465#endif
f927c5ae 466 signal (SIGSEGV, fatal_error_signal);
00eaaa32 467#ifdef SIGSYS
f927c5ae 468 signal (SIGSYS, fatal_error_signal);
00eaaa32 469#endif
f927c5ae
JB
470 signal (SIGTERM, fatal_error_signal);
471#ifdef SIGXCPU
472 signal (SIGXCPU, fatal_error_signal);
473#endif
474#ifdef SIGXFSZ
475 signal (SIGXFSZ, fatal_error_signal);
476#endif /* SIGXFSZ */
477
271c7b7c
RS
478#ifdef SIGDANGER
479 /* This just means available memory is getting low. */
480 signal (SIGDANGER, memory_warning_signal);
481#endif
482
f927c5ae 483#ifdef AIX
f927c5ae
JB
484 signal (20, fatal_error_signal);
485 signal (21, fatal_error_signal);
486 signal (22, fatal_error_signal);
f927c5ae 487 signal (24, fatal_error_signal);
86fb06ae
RS
488#if 0 /* mvn@library.ucla.edu says these are SIGIO on AIX 3.2.4. */
489 signal (23, fatal_error_signal);
bfb61299 490#ifdef SIGIO
f927c5ae
JB
491 signal (SIGAIO, fatal_error_signal);
492 signal (SIGPTY, fatal_error_signal);
bfb61299 493#endif
86fb06ae 494#endif
0aef8561 495#ifndef _I386
f927c5ae 496 signal (SIGIOINT, fatal_error_signal);
0aef8561 497#endif
f927c5ae
JB
498 signal (SIGGRANT, fatal_error_signal);
499 signal (SIGRETRACT, fatal_error_signal);
500 signal (SIGSOUND, fatal_error_signal);
501 signal (SIGMSG, fatal_error_signal);
502#endif /* AIX */
503 }
504
505 noninteractive1 = noninteractive;
506
507/* Perform basic initializations (not merely interning symbols) */
508
509 if (!initialized)
510 {
511 init_alloc_once ();
512 init_obarray ();
513 init_eval_once ();
514 init_syntax_once (); /* Create standard syntax table. */
515 /* Must be done before init_buffer */
516 init_casetab_once ();
517 init_buffer_once (); /* Create buffer table and some buffers */
518 init_minibuf_once (); /* Create list of minibuffers */
519 /* Must precede init_window_once */
520 init_window_once (); /* Init the window system */
521 }
522
523 init_alloc ();
f927c5ae
JB
524 init_eval ();
525 init_data ();
0e956009 526
29b89fe0
RS
527#ifdef MSDOS
528 /* Call early 'cause init_environment needs it. */
529 init_dosfns ();
530 /* Set defaults for several environment variables. */
531 if (initialized) init_environment (argc, argv, skip_args);
532#endif
533
0e956009
JB
534 /* egetenv is a pretty low-level facility, which may get called in
535 many circumstances; it seems flimsy to put off initializing it
536 until calling init_callproc. */
537 set_process_environment ();
93aed04d
RS
538 /* AIX crashes are reported in system versions 3.2.3 and 3.2.4
539 if this is not done. Do it after set_process_environment so that we
540 don't pollute Vprocess_environment. */
541#ifdef AIX
542 putenv ("LANG=C");
543#endif
0e956009 544
ace40a69
RS
545 init_buffer (); /* Init default directory of main buffer */
546
7928f0b5 547 init_callproc_1 (); /* Must precede init_cmdargs and init_sys_modes. */
ace40a69 548 init_cmdargs (argc, argv, skip_args); /* Must precede init_lread. */
7928f0b5 549 init_callproc (); /* Must follow init_cmdargs but not init_sys_modes. */
fb8e9847 550 init_lread ();
f927c5ae 551
f927c5ae
JB
552 if (!noninteractive)
553 {
554#ifdef VMS
1cbd5d9d 555 init_vms_input ();/* init_display calls get_frame_size, that needs this */
f927c5ae
JB
556#endif /* VMS */
557 init_display (); /* Determine terminal type. init_sys_modes uses results */
558 }
559 init_keyboard (); /* This too must precede init_sys_modes */
f927c5ae
JB
560#ifdef VMS
561 init_vmsproc (); /* And this too. */
562#endif /* VMS */
563 init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.) */
564 init_xdisp ();
565 init_macros ();
566 init_editfns ();
567#ifdef LISP_FLOAT_TYPE
568 init_floatfns ();
569#endif
570#ifdef VMS
571 init_vmsfns ();
572#endif /* VMS */
f927c5ae 573 init_process ();
32676c08
JB
574#ifdef CLASH_DETECTION
575 init_filelock ();
576#endif /* CLASH_DETECTION */
f927c5ae
JB
577
578/* Intern the names of all standard functions and variables; define standard keys */
579
580 if (!initialized)
581 {
582 /* The basic levels of Lisp must come first */
583 /* And data must come first of all
584 for the sake of symbols like error-message */
585 syms_of_data ();
586 syms_of_alloc ();
fb8e9847 587 syms_of_lread ();
f927c5ae
JB
588 syms_of_print ();
589 syms_of_eval ();
590 syms_of_fns ();
f927c5ae 591 syms_of_floatfns ();
f927c5ae
JB
592
593 syms_of_abbrev ();
594 syms_of_buffer ();
595 syms_of_bytecode ();
596 syms_of_callint ();
597 syms_of_casefiddle ();
598 syms_of_casetab ();
599 syms_of_callproc ();
600 syms_of_cmds ();
601#ifndef NO_DIR_LIBRARY
602 syms_of_dired ();
603#endif /* not NO_DIR_LIBRARY */
604 syms_of_display ();
605 syms_of_doc ();
606 syms_of_editfns ();
607 syms_of_emacs ();
608 syms_of_fileio ();
609#ifdef CLASH_DETECTION
610 syms_of_filelock ();
611#endif /* CLASH_DETECTION */
612 syms_of_indent ();
613 syms_of_keyboard ();
614 syms_of_keymap ();
615 syms_of_macros ();
616 syms_of_marker ();
617 syms_of_minibuf ();
618 syms_of_mocklisp ();
f927c5ae 619 syms_of_process ();
f927c5ae 620 syms_of_search ();
1cbd5d9d 621 syms_of_frame ();
f927c5ae
JB
622 syms_of_syntax ();
623 syms_of_undo ();
bef79ee4
JA
624
625 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
626 syms_of_textprop ();
f927c5ae
JB
627#ifdef VMS
628 syms_of_vmsproc ();
629#endif /* VMS */
630 syms_of_window ();
631 syms_of_xdisp ();
632#ifdef HAVE_X_WINDOWS
72412588 633 syms_of_xterm ();
f927c5ae 634 syms_of_xfns ();
9c3f23b7 635 syms_of_xfaces ();
72412588
JB
636#ifdef HAVE_X11
637 syms_of_xselect ();
638#endif
dbc4e1c1 639#ifdef HAVE_X_MENU
f927c5ae
JB
640 syms_of_xmenu ();
641#endif /* HAVE_X_MENU */
642#endif /* HAVE_X_WINDOWS */
643
644#ifdef SYMS_SYSTEM
645 SYMS_SYSTEM;
646#endif
647
648#ifdef SYMS_MACHINE
649 SYMS_MACHINE;
650#endif
651
652 keys_of_casefiddle ();
653 keys_of_cmds ();
654 keys_of_buffer ();
655 keys_of_keyboard ();
656 keys_of_keymap ();
657 keys_of_macros ();
658 keys_of_minibuf ();
659 keys_of_window ();
5e67fbc2 660 keys_of_frame ();
f927c5ae
JB
661 }
662
663 if (!initialized)
664 {
665 /* Handle -l loadup-and-dump, args passed by Makefile. */
666 if (argc > 2 + skip_args && !strcmp (argv[1 + skip_args], "-l"))
667 Vtop_level = Fcons (intern ("load"),
668 Fcons (build_string (argv[2 + skip_args]), Qnil));
669#ifdef CANNOT_DUMP
670 /* Unless next switch is -nl, load "loadup.el" first thing. */
671 if (!(argc > 1 + skip_args && !strcmp (argv[1 + skip_args], "-nl")))
672 Vtop_level = Fcons (intern ("load"),
673 Fcons (build_string ("loadup.el"), Qnil));
674#endif /* CANNOT_DUMP */
675 }
676
677 initialized = 1;
678
afe9fae9
RS
679#if defined (sun) || defined (LOCALTIME_CACHE)
680 /* sun's localtime has a bug. it caches the value of the time
279cc2b8
JB
681 zone rather than looking it up every time. Since localtime() is
682 called to bolt the undumping time into the undumped emacs, this
afe9fae9
RS
683 results in localtime ignoring the TZ environment variable.
684 This flushes the new TZ value into localtime. */
685 tzset ();
686#endif /* defined (sun) || defined (LOCALTIME_CACHE) */
279cc2b8 687
f927c5ae
JB
688 /* Enter editor command loop. This never returns. */
689 Frecursive_edit ();
690 /* NOTREACHED */
691}
692\f
693DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P",
edc8ae07 694 "Exit the Emacs job and kill it.\n\
f927c5ae
JB
695If ARG is an integer, return ARG as the exit program code.\n\
696If ARG is a string, stuff it as keyboard input.\n\n\
697The value of `kill-emacs-hook', if not void,\n\
698is a list of functions (of no args),\n\
699all of which are called before Emacs is actually killed.")
700 (arg)
701 Lisp_Object arg;
702{
703 Lisp_Object hook, hook1;
704 int i;
705 struct gcpro gcpro1;
706
707 GCPRO1 (arg);
708
709 if (feof (stdin))
710 arg = Qt;
711
2447c626 712 if (!NILP (Vrun_hooks) && !noninteractive)
f927c5ae
JB
713 call1 (Vrun_hooks, intern ("kill-emacs-hook"));
714
f927c5ae
JB
715 UNGCPRO;
716
717/* Is it really necessary to do this deassign
718 when we are going to exit anyway? */
719/* #ifdef VMS
720 stop_vms_input ();
721 #endif */
40be253a 722
d0068e25 723 shut_down_emacs (0, 0, STRINGP (arg) ? arg : Qnil);
40be253a 724
f927c5ae
JB
725 exit ((XTYPE (arg) == Lisp_Int) ? XINT (arg)
726#ifdef VMS
727 : 1
728#else
729 : 0
730#endif
731 );
732 /* NOTREACHED */
733}
40be253a
JB
734
735
736/* Perform an orderly shutdown of Emacs. Autosave any modified
737 buffers, kill any child processes, clean up the terminal modes (if
738 we're in the foreground), and other stuff like that. Don't perform
739 any redisplay; this may be called when Emacs is shutting down in
740 the background, or after its X connection has died.
741
742 If SIG is a signal number, print a message for it.
743
744 This is called by fatal signal handlers, X protocol error handlers,
745 and Fkill_emacs. */
f7ab4e3d 746
40be253a 747void
f7ab4e3d 748shut_down_emacs (sig, no_x, stuff)
41423a80 749 int sig, no_x;
f7ab4e3d 750 Lisp_Object stuff;
40be253a
JB
751{
752 /* If we are controlling the terminal, reset terminal modes */
753#ifdef EMACS_HAVE_TTY_PGRP
754 {
d04d81d2
RS
755 int pgrp = EMACS_GETPGRP (0);
756
40be253a
JB
757 int tpgrp;
758 if (EMACS_GET_TTY_PGRP (0, &tpgrp) != -1
5a570e37 759 && tpgrp == pgrp)
40be253a
JB
760 {
761 fflush (stdout);
762 reset_sys_modes ();
763 if (sig && sig != SIGTERM)
764 fprintf (stderr, "Fatal error (%d).", sig);
765 }
766 }
767#else
768 fflush (stdout);
769 reset_sys_modes ();
770#endif
771
f7ab4e3d
RS
772 stuff_buffered_input (stuff);
773
40be253a
JB
774 kill_buffer_processes (Qnil);
775 Fdo_auto_save (Qt, Qnil);
776
777#ifdef CLASH_DETECTION
778 unlock_all_files ();
779#endif
780
781#ifdef VMS
782 kill_vms_processes ();
783#endif
784
41423a80
RS
785#ifdef HAVE_X_WINDOWS
786 if (!noninteractive && EQ (Vwindow_system, intern ("x")) && ! no_x)
787 Fx_close_current_connection ();
788#endif /* HAVE_X_WINDOWS */
789
40be253a
JB
790#ifdef SIGIO
791 /* There is a tendency for a SIGIO signal to arrive within exit,
792 and cause a SIGHUP because the input descriptor is already closed. */
793 unrequest_sigio ();
794 signal (SIGIO, SIG_IGN);
795#endif
796}
797
798
f927c5ae
JB
799\f
800#ifndef CANNOT_DUMP
801/* Nothing like this can be implemented on an Apollo.
802 What a loss! */
803
804#ifdef HAVE_SHM
805
806DEFUN ("dump-emacs-data", Fdump_emacs_data, Sdump_emacs_data, 1, 1, 0,
807 "Dump current state of Emacs into data file FILENAME.\n\
808This function exists on systems that use HAVE_SHM.")
809 (intoname)
810 Lisp_Object intoname;
811{
812 extern int my_edata;
813 Lisp_Object tem;
814 extern void malloc_warning ();
815
816 CHECK_STRING (intoname, 0);
817 intoname = Fexpand_file_name (intoname, Qnil);
818
819 tem = Vpurify_flag;
820 Vpurify_flag = Qnil;
821
822 fflush (stdout);
823 /* Tell malloc where start of impure now is */
824 /* Also arrange for warnings when nearly out of space. */
825#ifndef SYSTEM_MALLOC
70eb2c3e 826 memory_warnings (&my_edata, malloc_warning);
f927c5ae
JB
827#endif
828 map_out_data (XSTRING (intoname)->data);
829
830 Vpurify_flag = tem;
831
832 return Qnil;
833}
834
835#else /* not HAVE_SHM */
836
837DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0,
838 "Dump current state of Emacs into executable file FILENAME.\n\
839Take symbols from SYMFILE (presumably the file you executed to run Emacs).\n\
840This is used in the file `loadup.el' when building Emacs.\n\
841\n\
842Bind `command-line-processed' to nil before dumping,\n\
843if you want the dumped Emacs to process its command line\n\
844and announce itself normally when it is run.")
845 (intoname, symname)
846 Lisp_Object intoname, symname;
847{
848 extern int my_edata;
849 Lisp_Object tem;
850 extern void malloc_warning ();
851
852 CHECK_STRING (intoname, 0);
853 intoname = Fexpand_file_name (intoname, Qnil);
2447c626 854 if (!NILP (symname))
f927c5ae
JB
855 {
856 CHECK_STRING (symname, 0);
857 if (XSTRING (symname)->size)
858 symname = Fexpand_file_name (symname, Qnil);
859 }
860
861 tem = Vpurify_flag;
862 Vpurify_flag = Qnil;
863
864 fflush (stdout);
865#ifdef VMS
866 mapout_data (XSTRING (intoname)->data);
867#else
868 /* Tell malloc where start of impure now is */
869 /* Also arrange for warnings when nearly out of space. */
870#ifndef SYSTEM_MALLOC
70eb2c3e 871 memory_warnings (&my_edata, malloc_warning);
f927c5ae
JB
872#endif
873 unexec (XSTRING (intoname)->data,
2447c626 874 !NILP (symname) ? XSTRING (symname)->data : 0, &my_edata, 0, 0);
f927c5ae
JB
875#endif /* not VMS */
876
877 Vpurify_flag = tem;
878
879 return Qnil;
880}
881
882#endif /* not HAVE_SHM */
883
884#endif /* not CANNOT_DUMP */
885\f
4b163808 886#ifndef SEPCHAR
f927c5ae
JB
887#define SEPCHAR ':'
888#endif
889
890Lisp_Object
891decode_env_path (evarname, defalt)
892 char *evarname, *defalt;
893{
894 register char *path, *p;
895 extern char *index ();
896
897 Lisp_Object lpath;
898
2447c626
JB
899 /* It's okay to use getenv here, because this function is only used
900 to initialize variables when Emacs starts up, and isn't called
901 after that. */
e065a56e
JB
902 if (evarname != 0)
903 path = (char *) getenv (evarname);
904 else
905 path = 0;
f927c5ae
JB
906 if (!path)
907 path = defalt;
908 lpath = Qnil;
909 while (1)
910 {
911 p = index (path, SEPCHAR);
912 if (!p) p = path + strlen (path);
913 lpath = Fcons (p - path ? make_string (path, p - path) : Qnil,
914 lpath);
915 if (*p)
916 path = p + 1;
917 else
918 break;
919 }
920 return Fnreverse (lpath);
921}
922
923syms_of_emacs ()
924{
83591e66 925#ifndef CANNOT_DUMP
f927c5ae
JB
926#ifdef HAVE_SHM
927 defsubr (&Sdump_emacs_data);
928#else
929 defsubr (&Sdump_emacs);
83591e66 930#endif
f927c5ae
JB
931#endif
932
933 defsubr (&Skill_emacs);
934
59653951 935 defsubr (&Sinvocation_name);
ace40a69 936 defsubr (&Sinvocation_directory);
59653951 937
f927c5ae
JB
938 DEFVAR_LISP ("command-line-args", &Vcommand_line_args,
939 "Args passed by shell to Emacs, as a list of strings.");
940
941 DEFVAR_LISP ("system-type", &Vsystem_type,
942 "Value is symbol indicating type of operating system you are using.");
943 Vsystem_type = intern (SYSTEM_TYPE);
944
271c7b7c
RS
945 DEFVAR_LISP ("system-configuration", &Vsystem_configuration,
946 "Value is string indicating configuration Emacs was built for.");
947 Vsystem_configuration = build_string (CONFIGURATION);
948
f927c5ae
JB
949 DEFVAR_BOOL ("noninteractive", &noninteractive1,
950 "Non-nil means Emacs is running without interactive terminal.");
e5d77022 951
e5d77022 952 DEFVAR_LISP ("kill-emacs-hook", &Vkill_emacs_hook,
edc8ae07
JB
953 "Hook to be run whenever kill-emacs is called.\n\
954Since kill-emacs may be invoked when the terminal is disconnected (or\n\
955in other similar situations), functions placed on this hook should not\n\
679aee02 956expect to be able to interact with the user.");
edc8ae07 957 Vkill_emacs_hook = Qnil;
3005da00
RS
958
959 DEFVAR_INT ("emacs-priority", &emacs_priority,
960 "Priority for Emacs to run at.\n\
961This value is effective only if set before Emacs is dumped,\n\
962and only if the Emacs executable is installed with setuid to permit\n\
963it to change priority. (Emacs sets its uid back to the real uid.)");
964 emacs_priority = 0;
59653951
JB
965
966 staticpro (&Vinvocation_name);
967 Vinvocation_name = Qnil;
ace40a69
RS
968 staticpro (&Vinvocation_directory);
969 Vinvocation_directory = Qnil;
f927c5ae 970}