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