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