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