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