(main) [VMS]: Fix var ref.
[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,97,98,1999,2001,02,03,2004
3 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22
23 #include <config.h>
24 #include <signal.h>
25 #include <errno.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 HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
38
39 #ifdef BSD_SYSTEM
40 #include <sys/ioctl.h>
41 #endif
42
43 #ifdef WINDOWSNT
44 #include <fcntl.h>
45 #endif
46
47 #include "lisp.h"
48 #include "commands.h"
49 #include "intervals.h"
50 #include "buffer.h"
51 #include "window.h"
52
53 #include "systty.h"
54 #include "blockinput.h"
55 #include "syssignal.h"
56 #include "process.h"
57 #include "termhooks.h"
58 #include "keyboard.h"
59 #include "keymap.h"
60
61 #ifdef HAVE_SETLOCALE
62 #include <locale.h>
63 #endif
64
65 #ifdef HAVE_SETRLIMIT
66 #include <sys/time.h>
67 #include <sys/resource.h>
68 #endif
69
70 #ifndef O_RDWR
71 #define O_RDWR 2
72 #endif
73
74 #ifdef HAVE_SETPGID
75 #if !defined (USG) || defined (BSD_PGRPS)
76 #undef setpgrp
77 #define setpgrp setpgid
78 #endif
79 #endif
80
81 extern void malloc_warning P_ ((char *));
82 extern void set_time_zone_rule P_ ((char *));
83 #ifdef HAVE_INDEX
84 extern char *index P_ ((const char *, int));
85 #endif
86
87 /* Make these values available in GDB, which doesn't see macros. */
88
89 #ifdef USE_LSB_TAG
90 int gdb_use_lsb = 1;
91 #else
92 int gdb_use_lsb = 0;
93 #endif
94 #ifdef NO_UNION_TYPE
95 int gdb_use_union = 0;
96 #else
97 int gdb_use_union = 1;
98 #endif
99 EMACS_INT gdb_valbits = VALBITS;
100 EMACS_INT gdb_gctypebits = GCTYPEBITS;
101 #ifdef DATA_SEG_BITS
102 EMACS_INT gdb_data_seg_bits = DATA_SEG_BITS;
103 #else
104 EMACS_INT gdb_data_seg_bits = 0;
105 #endif
106 EMACS_INT PVEC_FLAG = PSEUDOVECTOR_FLAG;
107
108 /* Command line args from shell, as list of strings. */
109 Lisp_Object Vcommand_line_args;
110
111 /* The name under which Emacs was invoked, with any leading directory
112 names discarded. */
113 Lisp_Object Vinvocation_name;
114
115 /* The directory name from which Emacs was invoked. */
116 Lisp_Object Vinvocation_directory;
117
118 /* The directory name in which to find subdirs such as lisp and etc.
119 nil means get them only from PATH_LOADSEARCH. */
120 Lisp_Object Vinstallation_directory;
121
122 /* Hook run by `kill-emacs' before it does really anything. */
123 Lisp_Object Vkill_emacs_hook;
124
125 /* An empty lisp string. To avoid having to build any other. */
126 Lisp_Object empty_string;
127
128 #ifdef SIGUSR1
129 /* Hooks for signal USR1 and USR2 handling. */
130 Lisp_Object Vsignal_USR1_hook;
131 #ifdef SIGUSR2
132 Lisp_Object Vsignal_USR2_hook;
133 #endif
134 #endif
135
136 /* Search path separator. */
137 Lisp_Object Vpath_separator;
138
139 /* Set nonzero after Emacs has started up the first time.
140 Prevents reinitialization of the Lisp world and keymaps
141 on subsequent starts. */
142 int initialized;
143
144 #ifdef DOUG_LEA_MALLOC
145 /* Preserves a pointer to the memory allocated that copies that
146 static data inside glibc's malloc. */
147 void *malloc_state_ptr;
148 /* From glibc, a routine that returns a copy of the malloc internal state. */
149 extern void *malloc_get_state ();
150 /* From glibc, a routine that overwrites the malloc internal state. */
151 extern void malloc_set_state ();
152 /* Non-zero if the MALLOC_CHECK_ enviroment variable was set while
153 dumping. Used to work around a bug in glibc's malloc. */
154 int malloc_using_checking;
155 #endif
156
157 /* Variable whose value is symbol giving operating system type. */
158 Lisp_Object Vsystem_type;
159
160 /* Variable whose value is string giving configuration built for. */
161 Lisp_Object Vsystem_configuration;
162
163 /* Variable whose value is string giving configuration options,
164 for use when reporting bugs. */
165 Lisp_Object Vsystem_configuration_options;
166
167 Lisp_Object Qfile_name_handler_alist;
168
169 /* Current and previous system locales for messages and time. */
170 Lisp_Object Vsystem_messages_locale;
171 Lisp_Object Vprevious_system_messages_locale;
172 Lisp_Object Vsystem_time_locale;
173 Lisp_Object Vprevious_system_time_locale;
174
175 /* If non-zero, emacs should not attempt to use a window-specific code,
176 but instead should use the virtual terminal under which it was started. */
177 int inhibit_window_system;
178
179 /* If nonzero, set Emacs to run at this priority. This is also used
180 in child_setup and sys_suspend to make sure subshells run at normal
181 priority; those functions have their own extern declaration. */
182 EMACS_INT emacs_priority;
183
184 /* If non-zero, a filter or a sentinel is running. Tested to save the match
185 data on the first attempt to change it inside asynchronous code. */
186 int running_asynch_code;
187
188 #ifdef BSD_PGRPS
189 /* See sysdep.c. */
190 extern int inherited_pgroup;
191 #endif
192
193 #ifdef HAVE_X_WINDOWS
194 /* If non-zero, -d was specified, meaning we're using some window system. */
195 int display_arg;
196 #endif
197
198 /* An address near the bottom of the stack.
199 Tells GC how to save a copy of the stack. */
200 char *stack_bottom;
201
202 #ifdef HAVE_WINDOW_SYSTEM
203 extern Lisp_Object Vwindow_system;
204 #endif /* HAVE_WINDOW_SYSTEM */
205
206 extern Lisp_Object Vauto_save_list_file_name;
207
208 #ifdef USG_SHARED_LIBRARIES
209 /* If nonzero, this is the place to put the end of the writable segment
210 at startup. */
211
212 unsigned int bss_end = 0;
213 #endif
214
215 /* Nonzero means running Emacs without interactive terminal. */
216
217 int noninteractive;
218
219 /* Value of Lisp variable `noninteractive'.
220 Normally same as C variable `noninteractive'
221 but nothing terrible happens if user sets this one. */
222
223 int noninteractive1;
224
225 /* Save argv and argc. */
226 char **initial_argv;
227 int initial_argc;
228
229 static void sort_args ();
230 void syms_of_emacs ();
231
232 /* MSVC needs each string be shorter than 2048 bytes, so the usage
233 strings below are split to not overflow this limit. */
234 #define USAGE1 "\
235 Usage: %s [OPTION-OR-FILENAME]...\n\
236 \n\
237 Run Emacs, the extensible, customizable, self-documenting real-time\n\
238 display editor. The recommended way to start Emacs for normal editing\n\
239 is with no options at all.\n\
240 \n\
241 Run M-x info RET m emacs RET m command arguments RET inside Emacs to\n\
242 read the main documentation for these command-line arguments.\n\
243 \n\
244 Initialization options:\n\
245 \n\
246 --batch do not do interactive display; implies -q\n\
247 --debug-init enable Emacs Lisp debugger for init file\n\
248 --display, -d DISPLAY use X server DISPLAY\n\
249 --multibyte, --no-unibyte inhibit the effect of EMACS_UNIBYTE\n\
250 --no-desktop do not load a saved desktop\n\
251 --no-init-file, -q load neither ~/.emacs nor default.el\n\
252 --no-shared-memory, -nl do not use shared memory\n\
253 --no-site-file do not load site-start.el\n\
254 --no-splash do not display a splash screen on startup\n\
255 --no-window-system, -nw don't communicate with X, ignoring $DISPLAY\n\
256 --script FILE run FILE as an Emacs Lisp script\n\
257 --terminal, -t DEVICE use DEVICE for terminal I/O\n\
258 --unibyte, --no-multibyte run Emacs in unibyte mode\n\
259 --user, -u USER load ~USER/.emacs instead of your own\n\
260 \n%s"
261
262 #define USAGE2 "\
263 Action options:\n\
264 \n\
265 FILE visit FILE using find-file\n\
266 +LINE FILE visit FILE using find-file, then go to line LINE\n\
267 +LINE:COLUMN FILE visit FILE using find-file, then go to line LINE,\n\
268 column COLUMN\n\
269 --directory, -L DIR add DIR to variable load-path\n\
270 --eval EXPR evaluate Emacs Lisp expression EXPR\n\
271 --execute EXPR evaluate Emacs Lisp expression EXPR\n\
272 --file FILE visit FILE using find-file\n\
273 --find-file FILE visit FILE using find-file\n\
274 --funcall, -f FUNC call Emacs Lisp function FUNC with no arguments\n\
275 --insert FILE insert contents of FILE into current buffer\n\
276 --kill exit without asking for confirmation\n\
277 --load, -l FILE load Emacs Lisp FILE using the load function\n\
278 --visit FILE visit FILE using find-file\n\
279 \n"
280
281 #define USAGE3 "\
282 Display options:\n\
283 \n\
284 --background-color, -bg COLOR window background color\n\
285 --border-color, -bd COLOR main border color\n\
286 --border-width, -bw WIDTH width of main border\n\
287 --color MODE color mode for character terminals;\n\
288 MODE defaults to `auto', and can also\n\
289 be `never', `auto', `always',\n\
290 or a mode name like `ansi8'\n\
291 --cursor-color, -cr COLOR color of the Emacs cursor indicating point\n\
292 --font, -fn FONT default font; must be fixed-width\n\
293 --foreground-color, -fg COLOR window foreground color\n\
294 --fullheight, -fh make the first frame high as the screen\n\
295 --fullscreen, -fs make first frame fullscreen\n\
296 --fullwidth, -fw make the first frame wide as the screen\n\
297 --geometry, -g GEOMETRY window geometry\n\
298 --horizontal-scroll-bars, -hb enable horizontal scroll bars\n\
299 --icon-type, -i use picture of gnu for Emacs icon\n\
300 --iconic start Emacs in iconified state\n\
301 --internal-border, -ib WIDTH width between text and main border\n\
302 --line-spacing, -lsp PIXELS additional space to put between lines\n\
303 --mouse-color, -ms COLOR mouse cursor color in Emacs window\n\
304 --name NAME title for initial Emacs frame\n\
305 --reverse-video, -r, -rv switch foreground and background\n\
306 --title, -T TITLE title for initial Emacs frame\n\
307 --vertical-scroll-bars, -vb enable vertical scroll bars\n\
308 --xrm XRESOURCES set additional X resources\n\
309 --help display this help and exit\n\
310 --version output version information and exit\n\
311 \n\
312 You can generally also specify long option names with a single -; for\n\
313 example, -batch as well as --batch. You can use any unambiguous\n\
314 abbreviation for a --option.\n\
315 \n\
316 Various environment variables and window system resources also affect\n\
317 Emacs' operation. See the main documentation.\n\
318 \n"
319
320 #define USAGE4 "\
321 Report bugs to %s. First, please see the Bugs\n\
322 section of the Emacs manual or the file BUGS.\n"
323
324 \f
325 /* Signal code for the fatal signal that was received. */
326 int fatal_error_code;
327
328 /* Nonzero if handling a fatal error already. */
329 int fatal_error_in_progress;
330
331 /* If non-null, call this function from fatal_error_signal before
332 committing suicide. */
333
334 void (*fatal_error_signal_hook) P_ ((void));
335
336
337 #ifdef SIGUSR1
338 SIGTYPE
339 handle_USR1_signal (sig)
340 int sig;
341 {
342 struct input_event buf;
343
344 bzero (&buf, sizeof buf);
345 buf.kind = USER_SIGNAL_EVENT;
346 buf.frame_or_window = selected_frame;
347
348 kbd_buffer_store_event (&buf);
349 }
350 #endif /* SIGUSR1 */
351
352 #ifdef SIGUSR2
353 SIGTYPE
354 handle_USR2_signal (sig)
355 int sig;
356 {
357 struct input_event buf;
358
359 bzero (&buf, sizeof buf);
360 buf.kind = USER_SIGNAL_EVENT;
361 buf.code = 1;
362 buf.frame_or_window = selected_frame;
363
364 kbd_buffer_store_event (&buf);
365 }
366 #endif /* SIGUSR2 */
367
368 /* Handle bus errors, invalid instruction, etc. */
369 SIGTYPE
370 fatal_error_signal (sig)
371 int sig;
372 {
373 fatal_error_code = sig;
374 signal (sig, SIG_DFL);
375
376 TOTALLY_UNBLOCK_INPUT;
377
378 /* If fatal error occurs in code below, avoid infinite recursion. */
379 if (! fatal_error_in_progress)
380 {
381 fatal_error_in_progress = 1;
382
383 shut_down_emacs (sig, 0, Qnil);
384 }
385
386 #ifdef VMS
387 LIB$STOP (SS$_ABORT);
388 #else
389 /* Signal the same code; this time it will really be fatal.
390 Remember that since we're in a signal handler, the signal we're
391 going to send is probably blocked, so we have to unblock it if we
392 want to really receive it. */
393 #ifndef MSDOS
394 sigunblock (sigmask (fatal_error_code));
395 #endif
396
397 if (fatal_error_signal_hook)
398 fatal_error_signal_hook ();
399
400 kill (getpid (), fatal_error_code);
401 #endif /* not VMS */
402 }
403
404 #ifdef SIGDANGER
405
406 /* Handler for SIGDANGER. */
407 SIGTYPE
408 memory_warning_signal (sig)
409 int sig;
410 {
411 signal (sig, memory_warning_signal);
412
413 malloc_warning ("Operating system warns that virtual memory is running low.\n");
414
415 /* It might be unsafe to call do_auto_save now. */
416 force_auto_save_soon ();
417 }
418 #endif
419
420 /* We define abort, rather than using it from the library,
421 so that GDB can return from a breakpoint here.
422 MSDOS has its own definition in msdos.c. */
423
424 #if ! defined (DOS_NT) && ! defined (NO_ABORT)
425
426 #ifndef ABORT_RETURN_TYPE
427 #define ABORT_RETURN_TYPE void
428 #endif
429
430 ABORT_RETURN_TYPE
431 abort ()
432 {
433 kill (getpid (), SIGABRT);
434 /* This shouldn't be executed, but it prevents a warning. */
435 exit (1);
436 }
437 #endif
438
439 \f
440 /* Code for dealing with Lisp access to the Unix command line. */
441
442 static void
443 init_cmdargs (argc, argv, skip_args)
444 int argc;
445 char **argv;
446 int skip_args;
447 {
448 register int i;
449 Lisp_Object name, dir, tem;
450 int count = SPECPDL_INDEX ();
451 Lisp_Object raw_name;
452
453 initial_argv = argv;
454 initial_argc = argc;
455
456 raw_name = build_string (argv[0]);
457
458 /* Add /: to the front of the name
459 if it would otherwise be treated as magic. */
460 tem = Ffind_file_name_handler (raw_name, Qt);
461 if (! NILP (tem))
462 raw_name = concat2 (build_string ("/:"), raw_name);
463
464 Vinvocation_name = Ffile_name_nondirectory (raw_name);
465 Vinvocation_directory = Ffile_name_directory (raw_name);
466
467 /* If we got no directory in argv[0], search PATH to find where
468 Emacs actually came from. */
469 if (NILP (Vinvocation_directory))
470 {
471 Lisp_Object found;
472 int yes = openp (Vexec_path, Vinvocation_name,
473 Vexec_suffixes, &found, make_number (X_OK));
474 if (yes == 1)
475 {
476 /* Add /: to the front of the name
477 if it would otherwise be treated as magic. */
478 tem = Ffind_file_name_handler (found, Qt);
479 if (! NILP (tem))
480 found = concat2 (build_string ("/:"), found);
481 Vinvocation_directory = Ffile_name_directory (found);
482 }
483 }
484
485 if (!NILP (Vinvocation_directory)
486 && NILP (Ffile_name_absolute_p (Vinvocation_directory)))
487 /* Emacs was started with relative path, like ./emacs.
488 Make it absolute. */
489 Vinvocation_directory = Fexpand_file_name (Vinvocation_directory, Qnil);
490
491 Vinstallation_directory = Qnil;
492
493 if (!NILP (Vinvocation_directory))
494 {
495 dir = Vinvocation_directory;
496 name = Fexpand_file_name (Vinvocation_name, dir);
497 while (1)
498 {
499 Lisp_Object tem, lib_src_exists;
500 Lisp_Object etc_exists, info_exists;
501
502 /* See if dir contains subdirs for use by Emacs.
503 Check for the ones that would exist in a build directory,
504 not including lisp and info. */
505 tem = Fexpand_file_name (build_string ("lib-src"), dir);
506 lib_src_exists = Ffile_exists_p (tem);
507
508 #ifdef MSDOS
509 /* MSDOS installations frequently remove lib-src, but we still
510 must set installation-directory, or else info won't find
511 its files (it uses the value of installation-directory). */
512 tem = Fexpand_file_name (build_string ("info"), dir);
513 info_exists = Ffile_exists_p (tem);
514 #else
515 info_exists = Qnil;
516 #endif
517
518 if (!NILP (lib_src_exists) || !NILP (info_exists))
519 {
520 tem = Fexpand_file_name (build_string ("etc"), dir);
521 etc_exists = Ffile_exists_p (tem);
522 if (!NILP (etc_exists))
523 {
524 Vinstallation_directory
525 = Ffile_name_as_directory (dir);
526 break;
527 }
528 }
529
530 /* See if dir's parent contains those subdirs. */
531 tem = Fexpand_file_name (build_string ("../lib-src"), dir);
532 lib_src_exists = Ffile_exists_p (tem);
533
534
535 #ifdef MSDOS
536 /* See the MSDOS commentary above. */
537 tem = Fexpand_file_name (build_string ("../info"), dir);
538 info_exists = Ffile_exists_p (tem);
539 #else
540 info_exists = Qnil;
541 #endif
542
543 if (!NILP (lib_src_exists) || !NILP (info_exists))
544 {
545 tem = Fexpand_file_name (build_string ("../etc"), dir);
546 etc_exists = Ffile_exists_p (tem);
547 if (!NILP (etc_exists))
548 {
549 tem = Fexpand_file_name (build_string (".."), dir);
550 Vinstallation_directory
551 = Ffile_name_as_directory (tem);
552 break;
553 }
554 }
555
556 /* If the Emacs executable is actually a link,
557 next try the dir that the link points into. */
558 tem = Ffile_symlink_p (name);
559 if (!NILP (tem))
560 {
561 name = Fexpand_file_name (tem, dir);
562 dir = Ffile_name_directory (name);
563 }
564 else
565 break;
566 }
567 }
568
569 Vcommand_line_args = Qnil;
570
571 for (i = argc - 1; i >= 0; i--)
572 {
573 if (i == 0 || i > skip_args)
574 Vcommand_line_args
575 = Fcons (build_string (argv[i]), Vcommand_line_args);
576 }
577
578 unbind_to (count, Qnil);
579 }
580
581 DEFUN ("invocation-name", Finvocation_name, Sinvocation_name, 0, 0, 0,
582 doc: /* Return the program name that was used to run Emacs.
583 Any directory names are omitted. */)
584 ()
585 {
586 return Fcopy_sequence (Vinvocation_name);
587 }
588
589 DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory,
590 0, 0, 0,
591 doc: /* Return the directory name in which the Emacs executable was located. */)
592 ()
593 {
594 return Fcopy_sequence (Vinvocation_directory);
595 }
596
597 \f
598 #ifdef VMS
599 #ifdef LINK_CRTL_SHARE
600 #ifdef SHARABLE_LIB_BUG
601 extern noshare char **environ;
602 #endif /* SHARABLE_LIB_BUG */
603 #endif /* LINK_CRTL_SHARE */
604 #endif /* VMS */
605
606 #ifdef HAVE_TZSET
607 /* A valid but unlikely value for the TZ environment value.
608 It is OK (though a bit slower) if the user actually chooses this value. */
609 static char dump_tz[] = "UtC0";
610 #endif
611
612 #ifndef ORDINARY_LINK
613 /* We don't include crtbegin.o and crtend.o in the link,
614 so these functions and variables might be missed.
615 Provide dummy definitions to avoid error.
616 (We don't have any real constructors or destructors.) */
617 #ifdef __GNUC__
618 #ifndef GCC_CTORS_IN_LIBC
619 void __do_global_ctors ()
620 {}
621 void __do_global_ctors_aux ()
622 {}
623 void __do_global_dtors ()
624 {}
625 /* GNU/Linux has a bug in its library; avoid an error. */
626 #ifndef GNU_LINUX
627 char * __CTOR_LIST__[2] = { (char *) (-1), 0 };
628 #endif
629 char * __DTOR_LIST__[2] = { (char *) (-1), 0 };
630 #endif /* GCC_CTORS_IN_LIBC */
631 void __main ()
632 {}
633 #endif /* __GNUC__ */
634 #endif /* ORDINARY_LINK */
635
636 /* Test whether the next argument in ARGV matches SSTR or a prefix of
637 LSTR (at least MINLEN characters). If so, then if VALPTR is non-null
638 (the argument is supposed to have a value) store in *VALPTR either
639 the next argument or the portion of this one after the equal sign.
640 ARGV is read starting at position *SKIPPTR; this index is advanced
641 by the number of arguments used.
642
643 Too bad we can't just use getopt for all of this, but we don't have
644 enough information to do it right. */
645
646 static int
647 argmatch (argv, argc, sstr, lstr, minlen, valptr, skipptr)
648 char **argv;
649 int argc;
650 char *sstr;
651 char *lstr;
652 int minlen;
653 char **valptr;
654 int *skipptr;
655 {
656 char *p = NULL;
657 int arglen;
658 char *arg;
659
660 /* Don't access argv[argc]; give up in advance. */
661 if (argc <= *skipptr + 1)
662 return 0;
663
664 arg = argv[*skipptr+1];
665 if (arg == NULL)
666 return 0;
667 if (strcmp (arg, sstr) == 0)
668 {
669 if (valptr != NULL)
670 {
671 *valptr = argv[*skipptr+2];
672 *skipptr += 2;
673 }
674 else
675 *skipptr += 1;
676 return 1;
677 }
678 arglen = (valptr != NULL && (p = index (arg, '=')) != NULL
679 ? p - arg : strlen (arg));
680 if (lstr == 0 || arglen < minlen || strncmp (arg, lstr, arglen) != 0)
681 return 0;
682 else if (valptr == NULL)
683 {
684 *skipptr += 1;
685 return 1;
686 }
687 else if (p != NULL)
688 {
689 *valptr = p+1;
690 *skipptr += 1;
691 return 1;
692 }
693 else if (argv[*skipptr+2] != NULL)
694 {
695 *valptr = argv[*skipptr+2];
696 *skipptr += 2;
697 return 1;
698 }
699 else
700 {
701 return 0;
702 }
703 }
704
705 #ifdef DOUG_LEA_MALLOC
706
707 /* malloc can be invoked even before main (e.g. by the dynamic
708 linker), so the dumped malloc state must be restored as early as
709 possible using this special hook. */
710
711 static void
712 malloc_initialize_hook ()
713 {
714 #ifndef USE_CRT_DLL
715 extern char **environ;
716 #endif
717
718 if (initialized)
719 {
720 if (!malloc_using_checking)
721 /* Work around a bug in glibc's malloc. MALLOC_CHECK_ must be
722 ignored if the heap to be restored was constructed without
723 malloc checking. Can't use unsetenv, since that calls malloc. */
724 {
725 char **p;
726
727 for (p = environ; p && *p; p++)
728 if (strncmp (*p, "MALLOC_CHECK_=", 14) == 0)
729 {
730 do
731 *p = p[1];
732 while (*++p);
733 break;
734 }
735 }
736
737 malloc_set_state (malloc_state_ptr);
738 free (malloc_state_ptr);
739 }
740 else
741 malloc_using_checking = getenv ("MALLOC_CHECK_") != NULL;
742 }
743
744 void (*__malloc_initialize_hook) () = malloc_initialize_hook;
745
746 #endif /* DOUG_LEA_MALLOC */
747
748
749 #define REPORT_EMACS_BUG_ADDRESS "bug-gnu-emacs@gnu.org"
750 #define REPORT_EMACS_BUG_PRETEST_ADDRESS "emacs-pretest-bug@gnu.org"
751
752 /* This function is used to determine an address to which bug report should
753 be sent. */
754
755 char *
756 bug_reporting_address ()
757 {
758 int count = 0;
759 Lisp_Object temp;
760 char *string;
761
762 temp = Fsymbol_value (intern ("emacs-version"));
763
764 /* When `emacs-version' is invalid, use normal address. */
765 if (!STRINGP(temp))
766 return REPORT_EMACS_BUG_ADDRESS;
767
768 string = SDATA (temp);
769
770 /* Count dots in `emacs-version'. */
771 while (*string)
772 {
773 if (*string == '.')
774 count++;
775 string++;
776 }
777
778 /* When `emacs-version' has at least three dots, it is development or
779 pretest version of Emacs. */
780 return count >= 3 ? REPORT_EMACS_BUG_PRETEST_ADDRESS : REPORT_EMACS_BUG_ADDRESS;
781 }
782
783
784 /* ARGSUSED */
785 int
786 main (argc, argv
787 #ifdef VMS
788 , envp
789 #endif
790 )
791 int argc;
792 char **argv;
793 #ifdef VMS
794 char **envp;
795 #endif
796 {
797 #if GC_MARK_STACK
798 Lisp_Object dummy;
799 #endif
800 char stack_bottom_variable;
801 int do_initial_setlocale;
802 int skip_args = 0;
803 #ifndef USE_CRT_DLL
804 extern int errno;
805 #endif
806 #ifdef HAVE_SETRLIMIT
807 struct rlimit rlim;
808 #endif
809 int no_loadup = 0;
810 char *junk = 0;
811
812 #if GC_MARK_STACK
813 extern Lisp_Object *stack_base;
814 stack_base = &dummy;
815 #endif
816
817 #ifdef LINUX_SBRK_BUG
818 __sbrk (1);
819 #endif
820
821 #ifdef RUN_TIME_REMAP
822 if (initialized)
823 run_time_remap (argv[0]);
824 #endif
825
826 #ifdef MAC_OSX
827 if (!initialized)
828 unexec_init_emacs_zone ();
829 #endif
830
831 sort_args (argc, argv);
832 argc = 0;
833 while (argv[argc]) argc++;
834
835 if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args)
836 /* We don't know the version number unless this is a dumped Emacs.
837 So ignore --version otherwise. */
838 && initialized)
839 {
840 Lisp_Object tem;
841 tem = Fsymbol_value (intern ("emacs-version"));
842 if (!STRINGP (tem))
843 {
844 fprintf (stderr, "Invalid value of `emacs-version'\n");
845 exit (1);
846 }
847 else
848 {
849 printf ("GNU Emacs %s\n", SDATA (tem));
850 printf ("Copyright (C) 2002 Free Software Foundation, Inc.\n");
851 printf ("GNU Emacs comes with ABSOLUTELY NO WARRANTY.\n");
852 printf ("You may redistribute copies of Emacs\n");
853 printf ("under the terms of the GNU General Public License.\n");
854 printf ("For more information about these matters, ");
855 printf ("see the file named COPYING.\n");
856 exit (0);
857 }
858 }
859
860 /* Map in shared memory, if we are using that. */
861 #ifdef HAVE_SHM
862 if (argmatch (argv, argc, "-nl", "--no-shared-memory", 6, NULL, &skip_args))
863 {
864 map_in_data (0);
865 /* The shared memory was just restored, which clobbered this. */
866 skip_args = 1;
867 }
868 else
869 {
870 map_in_data (1);
871 /* The shared memory was just restored, which clobbered this. */
872 skip_args = 0;
873 }
874 #endif
875
876 #ifdef NeXT
877 {
878 extern int malloc_cookie;
879 /* This helps out unexnext.c. */
880 if (initialized)
881 if (malloc_jumpstart (malloc_cookie) != 0)
882 printf ("malloc jumpstart failed!\n");
883 }
884 #endif /* NeXT */
885
886 #ifdef MAC_OSX
887 /* Skip process serial number passed in the form -psn_x_y as
888 command-line argument. */
889 if (argc > skip_args + 1 && strncmp (argv[skip_args+1], "-psn_", 5) == 0)
890 skip_args++;
891 #endif /* MAC_OSX */
892
893 #ifdef VMS
894 /* If -map specified, map the data file in. */
895 {
896 char *file;
897 if (argmatch (argv, argc, "-map", "--map-data", 3, &file, &skip_args))
898 mapin_data (file);
899 }
900
901 #ifdef LINK_CRTL_SHARE
902 #ifdef SHARABLE_LIB_BUG
903 /* Bletcherous shared libraries! */
904 if (!stdin)
905 stdin = fdopen (0, "r");
906 if (!stdout)
907 stdout = fdopen (1, "w");
908 if (!stderr)
909 stderr = fdopen (2, "w");
910 if (!environ)
911 environ = envp;
912 #endif /* SHARABLE_LIB_BUG */
913 #endif /* LINK_CRTL_SHARE */
914 #endif /* VMS */
915
916 #if defined (HAVE_SETRLIMIT) && defined (RLIMIT_STACK)
917 /* Extend the stack space available.
918 Don't do that if dumping, since some systems (e.g. DJGPP)
919 might define a smaller stack limit at that time. */
920 if (1
921 #ifndef CANNOT_DUMP
922 && (!noninteractive || initialized)
923 #endif
924 && !getrlimit (RLIMIT_STACK, &rlim))
925 {
926 long newlim;
927 extern int re_max_failures;
928 /* Approximate the amount regex.c needs per unit of re_max_failures. */
929 int ratio = 20 * sizeof (char *);
930 /* Then add 33% to cover the size of the smaller stacks that regex.c
931 successively allocates and discards, on its way to the maximum. */
932 ratio += ratio / 3;
933 /* Add in some extra to cover
934 what we're likely to use for other reasons. */
935 newlim = re_max_failures * ratio + 200000;
936 #ifdef __NetBSD__
937 /* NetBSD (at least NetBSD 1.2G and former) has a bug in its
938 stack allocation routine for new process that the allocation
939 fails if stack limit is not on page boundary. So, round up the
940 new limit to page boundary. */
941 newlim = (newlim + getpagesize () - 1) / getpagesize () * getpagesize();
942 #endif
943 if (newlim > rlim.rlim_max)
944 {
945 newlim = rlim.rlim_max;
946 /* Don't let regex.c overflow the stack we have. */
947 re_max_failures = (newlim - 200000) / ratio;
948 }
949 if (rlim.rlim_cur < newlim)
950 rlim.rlim_cur = newlim;
951
952 setrlimit (RLIMIT_STACK, &rlim);
953 }
954 #endif /* HAVE_SETRLIMIT and RLIMIT_STACK */
955
956 /* Record (approximately) where the stack begins. */
957 stack_bottom = &stack_bottom_variable;
958
959 #ifdef USG_SHARED_LIBRARIES
960 if (bss_end)
961 brk ((void *)bss_end);
962 #endif
963
964 clearerr (stdin);
965
966 #ifndef SYSTEM_MALLOC
967 /* Arrange to get warning messages as memory fills up. */
968 memory_warnings (0, malloc_warning);
969
970 /* Call malloc at least once, to run the initial __malloc_hook.
971 Also call realloc and free for consistency. */
972 free (realloc (malloc (4), 4));
973
974 /* Arrange to disable interrupt input inside malloc etc. */
975 uninterrupt_malloc ();
976 #endif /* not SYSTEM_MALLOC */
977
978 #if defined (MSDOS) || defined (WINDOWSNT)
979 /* We do all file input/output as binary files. When we need to translate
980 newlines, we do that manually. */
981 _fmode = O_BINARY;
982 #endif /* MSDOS || WINDOWSNT */
983
984 #ifdef MSDOS
985 #if __DJGPP__ >= 2
986 if (!isatty (fileno (stdin)))
987 setmode (fileno (stdin), O_BINARY);
988 if (!isatty (fileno (stdout)))
989 {
990 fflush (stdout);
991 setmode (fileno (stdout), O_BINARY);
992 }
993 #else /* not __DJGPP__ >= 2 */
994 (stdin)->_flag &= ~_IOTEXT;
995 (stdout)->_flag &= ~_IOTEXT;
996 (stderr)->_flag &= ~_IOTEXT;
997 #endif /* not __DJGPP__ >= 2 */
998 #endif /* MSDOS */
999
1000 #ifdef SET_EMACS_PRIORITY
1001 if (emacs_priority)
1002 nice (emacs_priority);
1003 setuid (getuid ());
1004 #endif /* SET_EMACS_PRIORITY */
1005
1006 /* Skip initial setlocale if LC_ALL is "C", as it's not needed in that case.
1007 The build procedure uses this while dumping, to ensure that the
1008 dumped Emacs does not have its system locale tables initialized,
1009 as that might cause screwups when the dumped Emacs starts up. */
1010 {
1011 char *lc_all = getenv ("LC_ALL");
1012 do_initial_setlocale = ! lc_all || strcmp (lc_all, "C");
1013 }
1014
1015 /* Set locale now, so that initial error messages are localized properly.
1016 fixup_locale must wait until later, since it builds strings. */
1017 if (do_initial_setlocale)
1018 setlocale (LC_ALL, "");
1019
1020 #ifdef EXTRA_INITIALIZE
1021 EXTRA_INITIALIZE;
1022 #endif
1023
1024 inhibit_window_system = 0;
1025
1026 /* Handle the -t switch, which specifies filename to use as terminal. */
1027 while (1)
1028 {
1029 char *term;
1030 if (argmatch (argv, argc, "-t", "--terminal", 4, &term, &skip_args))
1031 {
1032 int result;
1033 emacs_close (0);
1034 emacs_close (1);
1035 result = emacs_open (term, O_RDWR, 0);
1036 if (result < 0)
1037 {
1038 char *errstring = strerror (errno);
1039 fprintf (stderr, "%s: %s: %s\n", argv[0], term, errstring);
1040 exit (1);
1041 }
1042 dup (0);
1043 if (! isatty (0))
1044 {
1045 fprintf (stderr, "%s: %s: not a tty\n", argv[0], term);
1046 exit (1);
1047 }
1048 fprintf (stderr, "Using %s\n", term);
1049 #ifdef HAVE_WINDOW_SYSTEM
1050 inhibit_window_system = 1; /* -t => -nw */
1051 #endif
1052 }
1053 else
1054 break;
1055 }
1056
1057 /* Command line option --no-windows is deprecated and thus not mentioned
1058 in the manual and usage informations. */
1059 if (argmatch (argv, argc, "-nw", "--no-window-system", 6, NULL, &skip_args)
1060 || argmatch (argv, argc, "-nw", "--no-windows", 6, NULL, &skip_args))
1061 inhibit_window_system = 1;
1062
1063 /* Handle the -batch switch, which means don't do interactive display. */
1064 noninteractive = 0;
1065 if (argmatch (argv, argc, "-batch", "--batch", 5, NULL, &skip_args))
1066 noninteractive = 1;
1067 if (argmatch (argv, argc, "-script", "--script", 3, &junk, &skip_args))
1068 {
1069 noninteractive = 1; /* Set batch mode. */
1070 /* Convert --script to -l, un-skip it, and sort again so that -l will be
1071 handled in proper sequence. */
1072 argv[skip_args - 1] = "-l";
1073 skip_args -= 2;
1074 sort_args (argc, argv);
1075 }
1076
1077 /* Handle the --help option, which gives a usage message. */
1078 if (argmatch (argv, argc, "-help", "--help", 3, NULL, &skip_args))
1079 {
1080 printf (USAGE1, argv[0], USAGE2);
1081 printf (USAGE3);
1082 printf (USAGE4, bug_reporting_address ());
1083 exit (0);
1084 }
1085
1086 if (! noninteractive)
1087 {
1088 #ifdef BSD_PGRPS
1089 if (initialized)
1090 {
1091 inherited_pgroup = EMACS_GETPGRP (0);
1092 setpgrp (0, getpid ());
1093 }
1094 #else
1095 #if defined (USG5) && defined (INTERRUPT_INPUT)
1096 setpgrp ();
1097 #endif
1098 #endif
1099 }
1100
1101 init_signals ();
1102
1103 /* Don't catch SIGHUP if dumping. */
1104 if (1
1105 #ifndef CANNOT_DUMP
1106 && initialized
1107 #endif
1108 )
1109 {
1110 sigblock (sigmask (SIGHUP));
1111 /* In --batch mode, don't catch SIGHUP if already ignored.
1112 That makes nohup work. */
1113 if (! noninteractive
1114 || signal (SIGHUP, SIG_IGN) != SIG_IGN)
1115 signal (SIGHUP, fatal_error_signal);
1116 sigunblock (sigmask (SIGHUP));
1117 }
1118
1119 if (
1120 #ifndef CANNOT_DUMP
1121 ! noninteractive || initialized
1122 #else
1123 1
1124 #endif
1125 )
1126 {
1127 /* Don't catch these signals in batch mode if dumping.
1128 On some machines, this sets static data that would make
1129 signal fail to work right when the dumped Emacs is run. */
1130 signal (SIGQUIT, fatal_error_signal);
1131 signal (SIGILL, fatal_error_signal);
1132 signal (SIGTRAP, fatal_error_signal);
1133 #ifdef SIGUSR1
1134 signal (SIGUSR1, handle_USR1_signal);
1135 #ifdef SIGUSR2
1136 signal (SIGUSR2, handle_USR2_signal);
1137 #endif
1138 #endif
1139 #ifdef SIGABRT
1140 signal (SIGABRT, fatal_error_signal);
1141 #endif
1142 #ifdef SIGHWE
1143 signal (SIGHWE, fatal_error_signal);
1144 #endif
1145 #ifdef SIGPRE
1146 signal (SIGPRE, fatal_error_signal);
1147 #endif
1148 #ifdef SIGORE
1149 signal (SIGORE, fatal_error_signal);
1150 #endif
1151 #ifdef SIGUME
1152 signal (SIGUME, fatal_error_signal);
1153 #endif
1154 #ifdef SIGDLK
1155 signal (SIGDLK, fatal_error_signal);
1156 #endif
1157 #ifdef SIGCPULIM
1158 signal (SIGCPULIM, fatal_error_signal);
1159 #endif
1160 #ifdef SIGIOT
1161 /* This is missing on some systems - OS/2, for example. */
1162 signal (SIGIOT, fatal_error_signal);
1163 #endif
1164 #ifdef SIGEMT
1165 signal (SIGEMT, fatal_error_signal);
1166 #endif
1167 signal (SIGFPE, fatal_error_signal);
1168 #ifdef SIGBUS
1169 signal (SIGBUS, fatal_error_signal);
1170 #endif
1171 signal (SIGSEGV, fatal_error_signal);
1172 #ifdef SIGSYS
1173 signal (SIGSYS, fatal_error_signal);
1174 #endif
1175 signal (SIGTERM, fatal_error_signal);
1176 #ifdef SIGXCPU
1177 signal (SIGXCPU, fatal_error_signal);
1178 #endif
1179 #ifdef SIGXFSZ
1180 signal (SIGXFSZ, fatal_error_signal);
1181 #endif /* SIGXFSZ */
1182
1183 #ifdef SIGDANGER
1184 /* This just means available memory is getting low. */
1185 signal (SIGDANGER, memory_warning_signal);
1186 #endif
1187
1188 #ifdef AIX
1189 /* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */
1190 signal (SIGXCPU, fatal_error_signal);
1191 #ifndef _I386
1192 signal (SIGIOINT, fatal_error_signal);
1193 #endif
1194 signal (SIGGRANT, fatal_error_signal);
1195 signal (SIGRETRACT, fatal_error_signal);
1196 signal (SIGSOUND, fatal_error_signal);
1197 signal (SIGMSG, fatal_error_signal);
1198 #endif /* AIX */
1199 }
1200
1201 noninteractive1 = noninteractive;
1202
1203 /* Perform basic initializations (not merely interning symbols). */
1204
1205 if (!initialized)
1206 {
1207 init_alloc_once ();
1208 init_obarray ();
1209 init_eval_once ();
1210 init_charset_once ();
1211 init_coding_once ();
1212 init_syntax_once (); /* Create standard syntax table. */
1213 init_category_once (); /* Create standard category table. */
1214 /* Must be done before init_buffer. */
1215 init_casetab_once ();
1216 init_buffer_once (); /* Create buffer table and some buffers. */
1217 init_minibuf_once (); /* Create list of minibuffers. */
1218 /* Must precede init_window_once. */
1219
1220 /* Call syms_of_xfaces before init_window_once because that
1221 function creates Vterminal_frame. Termcap frames now use
1222 faces, and the face implementation uses some symbols as
1223 face names. */
1224 syms_of_xfaces ();
1225 /* Call syms_of_keyboard before init_window_once because
1226 keyboard sets up symbols that include some face names that
1227 the X support will want to use. This can happen when
1228 CANNOT_DUMP is defined. */
1229 syms_of_keyboard ();
1230
1231 #ifdef MAC_OS8
1232 /* init_window_once calls make_terminal_frame which on Mac OS
1233 creates a full-fledge output_mac type frame. This does not
1234 work correctly before syms_of_textprop, syms_of_macfns,
1235 syms_of_ccl, syms_of_fontset, syms_of_xterm, syms_of_search,
1236 syms_of_frame, mac_initialize, and init_keyboard have already
1237 been called. */
1238 syms_of_textprop ();
1239 syms_of_macfns ();
1240 syms_of_ccl ();
1241 syms_of_fontset ();
1242 syms_of_macterm ();
1243 syms_of_macmenu ();
1244 syms_of_data ();
1245 syms_of_search ();
1246 syms_of_frame ();
1247
1248 mac_initialize ();
1249 init_keyboard ();
1250 #endif
1251
1252 init_window_once (); /* Init the window system. */
1253 init_fileio_once (); /* Must precede any path manipulation. */
1254 #ifdef HAVE_WINDOW_SYSTEM
1255 init_fringe_once (); /* Swap bitmaps if necessary. */
1256 #endif /* HAVE_WINDOW_SYSTEM */
1257 }
1258
1259 init_alloc ();
1260
1261 if (do_initial_setlocale)
1262 {
1263 fixup_locale ();
1264 Vsystem_messages_locale = Vprevious_system_messages_locale;
1265 Vsystem_time_locale = Vprevious_system_time_locale;
1266 }
1267
1268 init_eval ();
1269 init_data ();
1270 #ifdef CLASH_DETECTION
1271 init_filelock ();
1272 #endif
1273 init_atimer ();
1274 running_asynch_code = 0;
1275
1276 /* Handle --unibyte and the EMACS_UNIBYTE envvar,
1277 but not while dumping. */
1278 if (1)
1279 {
1280 int inhibit_unibyte = 0;
1281
1282 /* --multibyte overrides EMACS_UNIBYTE. */
1283 if (argmatch (argv, argc, "-no-unibyte", "--no-unibyte", 4, NULL, &skip_args)
1284 || argmatch (argv, argc, "-multibyte", "--multibyte", 4, NULL, &skip_args)
1285 /* Ignore EMACS_UNIBYTE before dumping. */
1286 || (!initialized && noninteractive))
1287 inhibit_unibyte = 1;
1288
1289 /* --unibyte requests that we set up to do everything with single-byte
1290 buffers and strings. We need to handle this before calling
1291 init_lread, init_editfns and other places that generate Lisp strings
1292 from text in the environment. */
1293 /* Actually this shouldn't be needed as of 20.4 in a generally
1294 unibyte environment. As handa says, environment values
1295 aren't now decoded; also existing buffers are now made
1296 unibyte during startup if .emacs sets unibyte. Tested with
1297 8-bit data in environment variables and /etc/passwd, setting
1298 unibyte and Latin-1 in .emacs. -- Dave Love */
1299 if (argmatch (argv, argc, "-unibyte", "--unibyte", 4, NULL, &skip_args)
1300 || argmatch (argv, argc, "-no-multibyte", "--no-multibyte", 4, NULL, &skip_args)
1301 || (getenv ("EMACS_UNIBYTE") && !inhibit_unibyte))
1302 {
1303 Lisp_Object old_log_max;
1304 Lisp_Object symbol, tail;
1305
1306 symbol = intern ("default-enable-multibyte-characters");
1307 Fset (symbol, Qnil);
1308
1309 if (initialized)
1310 {
1311 /* Erase pre-dump messages in *Messages* now so no abort. */
1312 old_log_max = Vmessage_log_max;
1313 XSETFASTINT (Vmessage_log_max, 0);
1314 message_dolog ("", 0, 1, 0);
1315 Vmessage_log_max = old_log_max;
1316 }
1317
1318 for (tail = Vbuffer_alist; CONSP (tail);
1319 tail = XCDR (tail))
1320 {
1321 Lisp_Object buffer;
1322
1323 buffer = Fcdr (XCAR (tail));
1324 /* Verify that all buffers are empty now, as they
1325 ought to be. */
1326 if (BUF_Z (XBUFFER (buffer)) > BUF_BEG (XBUFFER (buffer)))
1327 abort ();
1328 /* It is safe to do this crudely in an empty buffer. */
1329 XBUFFER (buffer)->enable_multibyte_characters = Qnil;
1330 }
1331 }
1332 }
1333
1334 no_loadup
1335 = argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args);
1336
1337
1338 #ifdef HAVE_X_WINDOWS
1339 /* Stupid kludge to catch command-line display spec. We can't
1340 handle this argument entirely in window system dependent code
1341 because we don't even know which window system dependent code
1342 to run until we've recognized this argument. */
1343 {
1344 char *displayname = 0;
1345 int count_before = skip_args;
1346
1347 /* Skip any number of -d options, but only use the last one. */
1348 while (1)
1349 {
1350 int count_before_this = skip_args;
1351
1352 if (argmatch (argv, argc, "-d", "--display", 3, &displayname, &skip_args))
1353 display_arg = 1;
1354 else if (argmatch (argv, argc, "-display", 0, 3, &displayname, &skip_args))
1355 display_arg = 1;
1356 else
1357 break;
1358
1359 count_before = count_before_this;
1360 }
1361
1362 /* If we have the form --display=NAME,
1363 convert it into -d name.
1364 This requires inserting a new element into argv. */
1365 if (displayname != 0 && skip_args - count_before == 1)
1366 {
1367 char **new = (char **) xmalloc (sizeof (char *) * (argc + 2));
1368 int j;
1369
1370 for (j = 0; j < count_before + 1; j++)
1371 new[j] = argv[j];
1372 new[count_before + 1] = "-d";
1373 new[count_before + 2] = displayname;
1374 for (j = count_before + 2; j <argc; j++)
1375 new[j + 1] = argv[j];
1376 argv = new;
1377 argc++;
1378 }
1379 /* Change --display to -d, when its arg is separate. */
1380 else if (displayname != 0 && skip_args > count_before
1381 && argv[count_before + 1][1] == '-')
1382 argv[count_before + 1] = "-d";
1383
1384 /* Don't actually discard this arg. */
1385 skip_args = count_before;
1386 }
1387 #endif
1388
1389 /* argmatch must not be used after here,
1390 except when bulding temacs
1391 because the -d argument has not been skipped in skip_args. */
1392
1393 #ifdef MSDOS
1394 /* Call early 'cause init_environment needs it. */
1395 init_dosfns ();
1396 /* Set defaults for several environment variables. */
1397 if (initialized)
1398 init_environment (argc, argv, skip_args);
1399 else
1400 tzset ();
1401 #endif /* MSDOS */
1402
1403 #ifdef WINDOWSNT
1404 globals_of_w32 ();
1405 /* Initialize environment from registry settings. */
1406 init_environment (argv);
1407 init_ntproc (); /* must precede init_editfns. */
1408 #endif
1409
1410 #ifdef HAVE_CARBON
1411 if (initialized)
1412 init_mac_osx_environment ();
1413 #endif
1414
1415 /* egetenv is a pretty low-level facility, which may get called in
1416 many circumstances; it seems flimsy to put off initializing it
1417 until calling init_callproc. */
1418 set_process_environment ();
1419 /* AIX crashes are reported in system versions 3.2.3 and 3.2.4
1420 if this is not done. Do it after set_process_environment so that we
1421 don't pollute Vprocess_environment. */
1422 /* Setting LANG here will defeat the startup locale processing... */
1423 #ifdef AIX3_2
1424 putenv ("LANG=C");
1425 #endif
1426
1427 init_buffer (); /* Init default directory of main buffer. */
1428
1429 init_callproc_1 (); /* Must precede init_cmdargs and init_sys_modes. */
1430 init_cmdargs (argc, argv, skip_args); /* Must precede init_lread. */
1431
1432 if (initialized)
1433 {
1434 /* Erase any pre-dump messages in the message log, to avoid confusion. */
1435 Lisp_Object old_log_max;
1436 old_log_max = Vmessage_log_max;
1437 XSETFASTINT (Vmessage_log_max, 0);
1438 message_dolog ("", 0, 1, 0);
1439 Vmessage_log_max = old_log_max;
1440 }
1441
1442 init_callproc (); /* Must follow init_cmdargs but not init_sys_modes. */
1443 init_lread ();
1444
1445 /* Intern the names of all standard functions and variables;
1446 define standard keys. */
1447
1448 if (!initialized)
1449 {
1450 /* The basic levels of Lisp must come first. */
1451 /* And data must come first of all
1452 for the sake of symbols like error-message. */
1453 #ifndef MAC_OS8
1454 /* Called before init_window_once for Mac OS Classic. */
1455 syms_of_data ();
1456 #endif
1457 syms_of_alloc ();
1458 syms_of_lread ();
1459 syms_of_print ();
1460 syms_of_eval ();
1461 syms_of_fns ();
1462 syms_of_floatfns ();
1463
1464 syms_of_abbrev ();
1465 syms_of_buffer ();
1466 syms_of_bytecode ();
1467 syms_of_callint ();
1468 syms_of_casefiddle ();
1469 syms_of_casetab ();
1470 syms_of_callproc ();
1471 syms_of_category ();
1472 #ifndef MAC_OS8
1473 /* Called before init_window_once for Mac OS Classic. */
1474 syms_of_ccl ();
1475 #endif
1476 syms_of_charset ();
1477 syms_of_cmds ();
1478 #ifndef NO_DIR_LIBRARY
1479 syms_of_dired ();
1480 #endif /* not NO_DIR_LIBRARY */
1481 syms_of_display ();
1482 syms_of_doc ();
1483 syms_of_editfns ();
1484 syms_of_emacs ();
1485 syms_of_fileio ();
1486 syms_of_coding (); /* This should be after syms_of_fileio. */
1487 #ifdef CLASH_DETECTION
1488 syms_of_filelock ();
1489 #endif /* CLASH_DETECTION */
1490 syms_of_indent ();
1491 syms_of_insdel ();
1492 syms_of_keymap ();
1493 syms_of_macros ();
1494 syms_of_marker ();
1495 syms_of_minibuf ();
1496 syms_of_process ();
1497 #ifndef MAC_OS8
1498 /* Called before init_window_once for Mac OS Classic. */
1499 syms_of_search ();
1500 syms_of_frame ();
1501 #endif
1502 syms_of_syntax ();
1503 syms_of_term ();
1504 syms_of_undo ();
1505 #ifdef HAVE_SOUND
1506 syms_of_sound ();
1507 #endif
1508 #ifndef MAC_OS8
1509 /* Called before init_window_once for Mac OS Classic. */
1510 syms_of_textprop ();
1511 #endif
1512 syms_of_composite ();
1513 #ifdef VMS
1514 syms_of_vmsproc ();
1515 #endif /* VMS */
1516 #ifdef WINDOWSNT
1517 syms_of_ntproc ();
1518 #endif /* WINDOWSNT */
1519 syms_of_window ();
1520 syms_of_xdisp ();
1521 #ifdef HAVE_WINDOW_SYSTEM
1522 syms_of_fringe ();
1523 syms_of_image ();
1524 #endif /* HAVE_WINDOW_SYSTEM */
1525 #ifdef HAVE_X_WINDOWS
1526 syms_of_xterm ();
1527 syms_of_xfns ();
1528 syms_of_fontset ();
1529 #ifdef HAVE_X_SM
1530 syms_of_xsmfns ();
1531 #endif
1532 #ifdef HAVE_X11
1533 syms_of_xselect ();
1534 #endif
1535 #endif /* HAVE_X_WINDOWS */
1536
1537 #ifdef HAVE_MENUS
1538 #ifndef HAVE_NTGUI
1539 #ifndef MAC_OS
1540 /* Called before init_window_once for Mac OS Classic. */
1541 syms_of_xmenu ();
1542 #endif
1543 #endif
1544 #endif
1545
1546 #ifdef HAVE_NTGUI
1547 syms_of_w32term ();
1548 syms_of_w32fns ();
1549 syms_of_w32select ();
1550 syms_of_w32menu ();
1551 syms_of_fontset ();
1552 #endif /* HAVE_NTGUI */
1553
1554 #ifdef HAVE_CARBON
1555 syms_of_macterm ();
1556 syms_of_macfns ();
1557 syms_of_macmenu ();
1558 syms_of_fontset ();
1559 #endif /* HAVE_CARBON */
1560
1561 #ifdef SYMS_SYSTEM
1562 SYMS_SYSTEM;
1563 #endif
1564
1565 #ifdef SYMS_MACHINE
1566 SYMS_MACHINE;
1567 #endif
1568
1569 keys_of_casefiddle ();
1570 keys_of_cmds ();
1571 keys_of_buffer ();
1572 keys_of_keyboard ();
1573 keys_of_keymap ();
1574 keys_of_minibuf ();
1575 keys_of_window ();
1576 }
1577 else
1578 {
1579 /*
1580 Initialization that must be done even if the global variable
1581 initialized is non zero
1582 */
1583 #ifdef HAVE_NTGUI
1584 globals_of_w32fns ();
1585 globals_of_w32menu ();
1586 #endif /* end #ifdef HAVE_NTGUI */
1587 }
1588
1589 if (!noninteractive)
1590 {
1591 #ifdef VMS
1592 init_vms_input ();/* init_display calls get_frame_size, that needs this. */
1593 #endif /* VMS */
1594 init_display (); /* Determine terminal type. init_sys_modes uses results. */
1595 }
1596 #ifndef MAC_OS8
1597 /* Called before init_window_once for Mac OS Classic. */
1598 init_keyboard (); /* This too must precede init_sys_modes. */
1599 #endif
1600 #ifdef VMS
1601 init_vmsproc (); /* And this too. */
1602 #endif /* VMS */
1603 init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.). */
1604 init_fns ();
1605 init_xdisp ();
1606 #ifdef HAVE_WINDOW_SYSTEM
1607 init_fringe ();
1608 init_image ();
1609 #endif /* HAVE_WINDOW_SYSTEM */
1610 init_macros ();
1611 init_editfns ();
1612 init_floatfns ();
1613 #ifdef VMS
1614 init_vmsfns ();
1615 #endif /* VMS */
1616 init_process ();
1617 #ifdef HAVE_SOUND
1618 init_sound ();
1619 #endif
1620 init_window ();
1621
1622 if (!initialized)
1623 {
1624 char *file;
1625 /* Handle -l loadup, args passed by Makefile. */
1626 if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args))
1627 Vtop_level = Fcons (intern ("load"),
1628 Fcons (build_string (file), Qnil));
1629 /* Unless next switch is -nl, load "loadup.el" first thing. */
1630 if (! no_loadup)
1631 Vtop_level = Fcons (intern ("load"),
1632 Fcons (build_string ("loadup.el"), Qnil));
1633 }
1634
1635 if (initialized)
1636 {
1637 #ifdef HAVE_TZSET
1638 {
1639 /* If the execution TZ happens to be the same as the dump TZ,
1640 change it to some other value and then change it back,
1641 to force the underlying implementation to reload the TZ info.
1642 This is needed on implementations that load TZ info from files,
1643 since the TZ file contents may differ between dump and execution. */
1644 char *tz = getenv ("TZ");
1645 if (tz && !strcmp (tz, dump_tz))
1646 {
1647 ++*tz;
1648 tzset ();
1649 --*tz;
1650 }
1651 }
1652 #endif
1653 }
1654
1655 /* Set up for profiling. This is known to work on FreeBSD and
1656 GNU/Linux. It might work on some other systems too. Give it a
1657 try and tell us if it works on your system. To compile for
1658 profiling use something like `make CFLAGS="-pg -g -O -DPROFILING=1'. */
1659 #if defined (__FreeBSD__) || defined (__linux)
1660 #ifdef PROFILING
1661 if (initialized)
1662 {
1663 extern void _mcleanup ();
1664 extern char etext;
1665 extern void safe_bcopy ();
1666 extern void dump_opcode_frequencies ();
1667
1668 atexit (_mcleanup);
1669 /* This uses safe_bcopy because that function comes first in the
1670 Emacs executable. It might be better to use something that
1671 gives the start of the text segment, but start_of_text is not
1672 defined on all systems now. */
1673 monstartup (safe_bcopy, &etext);
1674 }
1675 else
1676 moncontrol (0);
1677 #endif
1678 #endif
1679
1680 initialized = 1;
1681
1682 #ifdef LOCALTIME_CACHE
1683 /* Some versions of localtime have a bug. They cache the value of the time
1684 zone rather than looking it up every time. Since localtime() is
1685 called to bolt the undumping time into the undumped emacs, this
1686 results in localtime ignoring the TZ environment variable.
1687 This flushes the new TZ value into localtime. */
1688 tzset ();
1689 #endif /* defined (LOCALTIME_CACHE) */
1690
1691 /* Enter editor command loop. This never returns. */
1692 Frecursive_edit ();
1693 /* NOTREACHED */
1694 return 0;
1695 }
1696 \f
1697 /* Sort the args so we can find the most important ones
1698 at the beginning of argv. */
1699
1700 /* First, here's a table of all the standard options. */
1701
1702 struct standard_args
1703 {
1704 char *name;
1705 char *longname;
1706 int priority;
1707 int nargs;
1708 };
1709
1710 struct standard_args standard_args[] =
1711 {
1712 { "-version", "--version", 150, 0 },
1713 #ifdef HAVE_SHM
1714 { "-nl", "--no-shared-memory", 140, 0 },
1715 #endif
1716 #ifdef VMS
1717 { "-map", "--map-data", 130, 0 },
1718 #endif
1719 { "-t", "--terminal", 120, 1 },
1720 { "-nw", "--no-window-system", 110, 0 },
1721 { "-nw", "--no-windows", 110, 0 },
1722 { "-batch", "--batch", 100, 0 },
1723 { "-script", "--script", 100, 1 },
1724 { "-help", "--help", 90, 0 },
1725 { "-no-unibyte", "--no-unibyte", 83, 0 },
1726 { "-multibyte", "--multibyte", 82, 0 },
1727 { "-unibyte", "--unibyte", 81, 0 },
1728 { "-no-multibyte", "--no-multibyte", 80, 0 },
1729 { "-nl", "--no-loadup", 70, 0 },
1730 /* -d must come last before the options handled in startup.el. */
1731 { "-d", "--display", 60, 1 },
1732 { "-display", 0, 60, 1 },
1733 /* Now for the options handled in startup.el. */
1734 { "-q", "--no-init-file", 50, 0 },
1735 { "-no-init-file", 0, 50, 0 },
1736 { "-no-site-file", "--no-site-file", 40, 0 },
1737 { "-no-splash", "--no-splash", 40, 0 },
1738 { "-u", "--user", 30, 1 },
1739 { "-user", 0, 30, 1 },
1740 { "-debug-init", "--debug-init", 20, 0 },
1741 { "-i", "--icon-type", 15, 0 },
1742 { "-itype", 0, 15, 0 },
1743 { "-iconic", "--iconic", 15, 0 },
1744 { "-bg", "--background-color", 10, 1 },
1745 { "-background", 0, 10, 1 },
1746 { "-fg", "--foreground-color", 10, 1 },
1747 { "-foreground", 0, 10, 1 },
1748 { "-bd", "--border-color", 10, 1 },
1749 { "-bw", "--border-width", 10, 1 },
1750 { "-ib", "--internal-border", 10, 1 },
1751 { "-ms", "--mouse-color", 10, 1 },
1752 { "-cr", "--cursor-color", 10, 1 },
1753 { "-fn", "--font", 10, 1 },
1754 { "-font", 0, 10, 1 },
1755 { "-fs", "--fullscreen", 10, 0 },
1756 { "-fw", "--fullwidth", 10, 0 },
1757 { "-fh", "--fullheight", 10, 0 },
1758 { "-g", "--geometry", 10, 1 },
1759 { "-geometry", 0, 10, 1 },
1760 { "-T", "--title", 10, 1 },
1761 { "-title", 0, 10, 1 },
1762 { "-name", "--name", 10, 1 },
1763 { "-xrm", "--xrm", 10, 1 },
1764 { "-r", "--reverse-video", 5, 0 },
1765 { "-rv", 0, 5, 0 },
1766 { "-reverse", 0, 5, 0 },
1767 { "-hb", "--horizontal-scroll-bars", 5, 0 },
1768 { "-vb", "--vertical-scroll-bars", 5, 0 },
1769 { "-color", "--color", 5, 0},
1770 /* These have the same priority as ordinary file name args,
1771 so they are not reordered with respect to those. */
1772 { "-L", "--directory", 0, 1 },
1773 { "-directory", 0, 0, 1 },
1774 { "-l", "--load", 0, 1 },
1775 { "-load", 0, 0, 1 },
1776 { "-f", "--funcall", 0, 1 },
1777 { "-funcall", 0, 0, 1 },
1778 { "-eval", "--eval", 0, 1 },
1779 { "-execute", "--execute", 0, 1 },
1780 { "-find-file", "--find-file", 0, 1 },
1781 { "-visit", "--visit", 0, 1 },
1782 { "-file", "--file", 0, 1 },
1783 { "-insert", "--insert", 0, 1 },
1784 /* This should be processed after ordinary file name args and the like. */
1785 { "-kill", "--kill", -10, 0 },
1786 };
1787
1788 /* Reorder the elements of ARGV (assumed to have ARGC elements)
1789 so that the highest priority ones come first.
1790 Do not change the order of elements of equal priority.
1791 If an option takes an argument, keep it and its argument together.
1792
1793 If an option that takes no argument appears more
1794 than once, eliminate all but one copy of it. */
1795
1796 static void
1797 sort_args (argc, argv)
1798 int argc;
1799 char **argv;
1800 {
1801 char **new = (char **) xmalloc (sizeof (char *) * argc);
1802 /* For each element of argv,
1803 the corresponding element of options is:
1804 0 for an option that takes no arguments,
1805 1 for an option that takes one argument, etc.
1806 -1 for an ordinary non-option argument. */
1807 int *options = (int *) xmalloc (sizeof (int) * argc);
1808 int *priority = (int *) xmalloc (sizeof (int) * argc);
1809 int to = 1;
1810 int incoming_used = 1;
1811 int from;
1812 int i;
1813
1814 /* Categorize all the options,
1815 and figure out which argv elts are option arguments. */
1816 for (from = 1; from < argc; from++)
1817 {
1818 options[from] = -1;
1819 priority[from] = 0;
1820 if (argv[from][0] == '-')
1821 {
1822 int match, thislen;
1823 char *equals;
1824
1825 /* If we have found "--", don't consider
1826 any more arguments as options. */
1827 if (argv[from][1] == '-' && argv[from][2] == 0)
1828 {
1829 /* Leave the "--", and everything following it, at the end. */
1830 for (; from < argc; from++)
1831 {
1832 priority[from] = -100;
1833 options[from] = -1;
1834 }
1835 break;
1836 }
1837
1838 /* Look for a match with a known old-fashioned option. */
1839 for (i = 0; i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
1840 if (!strcmp (argv[from], standard_args[i].name))
1841 {
1842 options[from] = standard_args[i].nargs;
1843 priority[from] = standard_args[i].priority;
1844 if (from + standard_args[i].nargs >= argc)
1845 fatal ("Option `%s' requires an argument\n", argv[from]);
1846 from += standard_args[i].nargs;
1847 goto done;
1848 }
1849
1850 /* Look for a match with a known long option.
1851 MATCH is -1 if no match so far, -2 if two or more matches so far,
1852 >= 0 (the table index of the match) if just one match so far. */
1853 if (argv[from][1] == '-')
1854 {
1855 match = -1;
1856 thislen = strlen (argv[from]);
1857 equals = index (argv[from], '=');
1858 if (equals != 0)
1859 thislen = equals - argv[from];
1860
1861 for (i = 0;
1862 i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
1863 if (standard_args[i].longname
1864 && !strncmp (argv[from], standard_args[i].longname,
1865 thislen))
1866 {
1867 if (match == -1)
1868 match = i;
1869 else
1870 match = -2;
1871 }
1872
1873 /* If we found exactly one match, use that. */
1874 if (match >= 0)
1875 {
1876 options[from] = standard_args[match].nargs;
1877 priority[from] = standard_args[match].priority;
1878 /* If --OPTION=VALUE syntax is used,
1879 this option uses just one argv element. */
1880 if (equals != 0)
1881 options[from] = 0;
1882 if (from + options[from] >= argc)
1883 fatal ("Option `%s' requires an argument\n", argv[from]);
1884 from += options[from];
1885 }
1886 }
1887 done: ;
1888 }
1889 }
1890
1891 /* Copy the arguments, in order of decreasing priority, to NEW. */
1892 new[0] = argv[0];
1893 while (incoming_used < argc)
1894 {
1895 int best = -1;
1896 int best_priority = -9999;
1897
1898 /* Find the highest priority remaining option.
1899 If several have equal priority, take the first of them. */
1900 for (from = 1; from < argc; from++)
1901 {
1902 if (argv[from] != 0 && priority[from] > best_priority)
1903 {
1904 best_priority = priority[from];
1905 best = from;
1906 }
1907 /* Skip option arguments--they are tied to the options. */
1908 if (options[from] > 0)
1909 from += options[from];
1910 }
1911
1912 if (best < 0)
1913 abort ();
1914
1915 /* Copy the highest priority remaining option, with its args, to NEW.
1916 Unless it is a duplicate of the previous one. */
1917 if (! (options[best] == 0
1918 && ! strcmp (new[to - 1], argv[best])))
1919 {
1920 new[to++] = argv[best];
1921 for (i = 0; i < options[best]; i++)
1922 new[to++] = argv[best + i + 1];
1923 }
1924
1925 incoming_used += 1 + (options[best] > 0 ? options[best] : 0);
1926
1927 /* Clear out this option in ARGV. */
1928 argv[best] = 0;
1929 for (i = 0; i < options[best]; i++)
1930 argv[best + i + 1] = 0;
1931 }
1932
1933 /* If duplicate options were deleted, fill up extra space with null ptrs. */
1934 while (to < argc)
1935 new[to++] = 0;
1936
1937 bcopy (new, argv, sizeof (char *) * argc);
1938
1939 free (options);
1940 free (new);
1941 free (priority);
1942 }
1943 \f
1944 DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P",
1945 doc: /* Exit the Emacs job and kill it.
1946 If ARG is an integer, return ARG as the exit program code.
1947 If ARG is a string, stuff it as keyboard input.
1948
1949 The value of `kill-emacs-hook', if not void,
1950 is a list of functions (of no args),
1951 all of which are called before Emacs is actually killed. */)
1952 (arg)
1953 Lisp_Object arg;
1954 {
1955 struct gcpro gcpro1;
1956
1957 GCPRO1 (arg);
1958
1959 if (feof (stdin))
1960 arg = Qt;
1961
1962 if (!NILP (Vrun_hooks) && !noninteractive)
1963 call1 (Vrun_hooks, intern ("kill-emacs-hook"));
1964
1965 UNGCPRO;
1966
1967 /* Is it really necessary to do this deassign
1968 when we are going to exit anyway? */
1969 /* #ifdef VMS
1970 stop_vms_input ();
1971 #endif */
1972
1973 shut_down_emacs (0, 0, STRINGP (arg) ? arg : Qnil);
1974
1975 /* If we have an auto-save list file,
1976 kill it because we are exiting Emacs deliberately (not crashing).
1977 Do it after shut_down_emacs, which does an auto-save. */
1978 if (STRINGP (Vauto_save_list_file_name))
1979 unlink (SDATA (Vauto_save_list_file_name));
1980
1981 exit (INTEGERP (arg) ? XINT (arg)
1982 #ifdef VMS
1983 : 1
1984 #else
1985 : 0
1986 #endif
1987 );
1988 /* NOTREACHED */
1989 }
1990
1991
1992 /* Perform an orderly shutdown of Emacs. Autosave any modified
1993 buffers, kill any child processes, clean up the terminal modes (if
1994 we're in the foreground), and other stuff like that. Don't perform
1995 any redisplay; this may be called when Emacs is shutting down in
1996 the background, or after its X connection has died.
1997
1998 If SIG is a signal number, print a message for it.
1999
2000 This is called by fatal signal handlers, X protocol error handlers,
2001 and Fkill_emacs. */
2002
2003 void
2004 shut_down_emacs (sig, no_x, stuff)
2005 int sig, no_x;
2006 Lisp_Object stuff;
2007 {
2008 /* Prevent running of hooks from now on. */
2009 Vrun_hooks = Qnil;
2010
2011 /* If we are controlling the terminal, reset terminal modes. */
2012 #ifdef EMACS_HAVE_TTY_PGRP
2013 {
2014 int pgrp = EMACS_GETPGRP (0);
2015
2016 int tpgrp;
2017 if (EMACS_GET_TTY_PGRP (0, &tpgrp) != -1
2018 && tpgrp == pgrp)
2019 {
2020 fflush (stdout);
2021 reset_sys_modes ();
2022 if (sig && sig != SIGTERM)
2023 fprintf (stderr, "Fatal error (%d)", sig);
2024 }
2025 }
2026 #else
2027 fflush (stdout);
2028 reset_sys_modes ();
2029 #endif
2030
2031 stuff_buffered_input (stuff);
2032
2033 kill_buffer_processes (Qnil);
2034 Fdo_auto_save (Qt, Qnil);
2035
2036 #ifdef CLASH_DETECTION
2037 unlock_all_files ();
2038 #endif
2039
2040 #ifdef VMS
2041 kill_vms_processes ();
2042 #endif
2043
2044 #if 0 /* This triggers a bug in XCloseDisplay and is not needed. */
2045 #ifdef HAVE_X_WINDOWS
2046 /* It's not safe to call intern here. Maybe we are crashing. */
2047 if (!noninteractive && SYMBOLP (Vwindow_system)
2048 && SCHARS (SYMBOL_NAME (Vwindow_system)) == 1
2049 && SREF (SYMBOL_NAME (Vwindow_system), 0) == 'x'
2050 && ! no_x)
2051 Fx_close_current_connection ();
2052 #endif /* HAVE_X_WINDOWS */
2053 #endif
2054
2055 #ifdef SIGIO
2056 /* There is a tendency for a SIGIO signal to arrive within exit,
2057 and cause a SIGHUP because the input descriptor is already closed. */
2058 unrequest_sigio ();
2059 signal (SIGIO, SIG_IGN);
2060 #endif
2061
2062 #ifdef WINDOWSNT
2063 term_ntproc ();
2064 #endif
2065
2066 /* Do this only if terminating normally, we want glyph matrices
2067 etc. in a core dump. */
2068 if (sig == 0 || sig == SIGTERM)
2069 {
2070 check_glyph_memory ();
2071 check_message_stack ();
2072 }
2073
2074 #ifdef MSDOS
2075 dos_cleanup ();
2076 #endif
2077 }
2078
2079
2080 \f
2081 #ifndef CANNOT_DUMP
2082
2083 #ifdef HAVE_SHM
2084
2085 DEFUN ("dump-emacs-data", Fdump_emacs_data, Sdump_emacs_data, 1, 1, 0,
2086 doc: /* Dump current state of Emacs into data file FILENAME.
2087 This function exists on systems that use HAVE_SHM. */)
2088 (filename)
2089 Lisp_Object filename;
2090 {
2091 extern char my_edata[];
2092 Lisp_Object tem;
2093
2094 check_pure_size ();
2095 CHECK_STRING (filename);
2096 filename = Fexpand_file_name (filename, Qnil);
2097
2098 tem = Vpurify_flag;
2099 Vpurify_flag = Qnil;
2100
2101 fflush (stdout);
2102 /* Tell malloc where start of impure now is. */
2103 /* Also arrange for warnings when nearly out of space. */
2104 #ifndef SYSTEM_MALLOC
2105 memory_warnings (my_edata, malloc_warning);
2106 #endif
2107 map_out_data (SDATA (filename));
2108
2109 Vpurify_flag = tem;
2110
2111 return Qnil;
2112 }
2113
2114 #else /* not HAVE_SHM */
2115
2116 DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0,
2117 doc: /* Dump current state of Emacs into executable file FILENAME.
2118 Take symbols from SYMFILE (presumably the file you executed to run Emacs).
2119 This is used in the file `loadup.el' when building Emacs.
2120
2121 You must run Emacs in batch mode in order to dump it. */)
2122 (filename, symfile)
2123 Lisp_Object filename, symfile;
2124 {
2125 extern char my_edata[];
2126 Lisp_Object tem;
2127 Lisp_Object symbol;
2128 int count = SPECPDL_INDEX ();
2129
2130 check_pure_size ();
2131
2132 if (! noninteractive)
2133 error ("Dumping Emacs works only in batch mode");
2134
2135 /* Bind `command-line-processed' to nil before dumping,
2136 so that the dumped Emacs will process its command line
2137 and set up to work with X windows if appropriate. */
2138 symbol = intern ("command-line-processed");
2139 specbind (symbol, Qnil);
2140
2141 CHECK_STRING (filename);
2142 filename = Fexpand_file_name (filename, Qnil);
2143 if (!NILP (symfile))
2144 {
2145 CHECK_STRING (symfile);
2146 if (SCHARS (symfile))
2147 symfile = Fexpand_file_name (symfile, Qnil);
2148 }
2149
2150 tem = Vpurify_flag;
2151 Vpurify_flag = Qnil;
2152
2153 #ifdef HAVE_TZSET
2154 set_time_zone_rule (dump_tz);
2155 #ifndef LOCALTIME_CACHE
2156 /* Force a tz reload, since set_time_zone_rule doesn't. */
2157 tzset ();
2158 #endif
2159 #endif
2160
2161 fflush (stdout);
2162 #ifdef VMS
2163 mapout_data (SDATA (filename));
2164 #else
2165 /* Tell malloc where start of impure now is. */
2166 /* Also arrange for warnings when nearly out of space. */
2167 #ifndef SYSTEM_MALLOC
2168 #ifndef WINDOWSNT
2169 /* On Windows, this was done before dumping, and that once suffices.
2170 Meanwhile, my_edata is not valid on Windows. */
2171 memory_warnings (my_edata, malloc_warning);
2172 #endif /* not WINDOWSNT */
2173 #endif
2174 #ifdef DOUG_LEA_MALLOC
2175 malloc_state_ptr = malloc_get_state ();
2176 #endif
2177
2178 #ifdef USE_MMAP_FOR_BUFFERS
2179 mmap_set_vars (0);
2180 #endif
2181 unexec (SDATA (filename),
2182 !NILP (symfile) ? SDATA (symfile) : 0, my_edata, 0, 0);
2183 #ifdef USE_MMAP_FOR_BUFFERS
2184 mmap_set_vars (1);
2185 #endif
2186 #ifdef DOUG_LEA_MALLOC
2187 free (malloc_state_ptr);
2188 #endif
2189 #endif /* not VMS */
2190
2191 Vpurify_flag = tem;
2192
2193 return unbind_to (count, Qnil);
2194 }
2195
2196 #endif /* not HAVE_SHM */
2197
2198 #endif /* not CANNOT_DUMP */
2199 \f
2200 #if HAVE_SETLOCALE
2201 /* Recover from setlocale (LC_ALL, ""). */
2202 void
2203 fixup_locale ()
2204 {
2205 /* The Emacs Lisp reader needs LC_NUMERIC to be "C",
2206 so that numbers are read and printed properly for Emacs Lisp. */
2207 setlocale (LC_NUMERIC, "C");
2208 }
2209
2210 /* Set system locale CATEGORY, with previous locale *PLOCALE, to
2211 DESIRED_LOCALE. */
2212 static void
2213 synchronize_locale (category, plocale, desired_locale)
2214 int category;
2215 Lisp_Object *plocale;
2216 Lisp_Object desired_locale;
2217 {
2218 if (! EQ (*plocale, desired_locale))
2219 {
2220 *plocale = desired_locale;
2221 setlocale (category, (STRINGP (desired_locale)
2222 ? (char *)(SDATA (desired_locale))
2223 : ""));
2224 }
2225 }
2226
2227 /* Set system time locale to match Vsystem_time_locale, if possible. */
2228 void
2229 synchronize_system_time_locale ()
2230 {
2231 synchronize_locale (LC_TIME, &Vprevious_system_time_locale,
2232 Vsystem_time_locale);
2233 }
2234
2235 /* Set system messages locale to match Vsystem_messages_locale, if
2236 possible. */
2237 void
2238 synchronize_system_messages_locale ()
2239 {
2240 #ifdef LC_MESSAGES
2241 synchronize_locale (LC_MESSAGES, &Vprevious_system_messages_locale,
2242 Vsystem_messages_locale);
2243 #endif
2244 }
2245 #endif /* HAVE_SETLOCALE */
2246 \f
2247 #ifndef SEPCHAR
2248 #define SEPCHAR ':'
2249 #endif
2250
2251 Lisp_Object
2252 decode_env_path (evarname, defalt)
2253 char *evarname, *defalt;
2254 {
2255 register char *path, *p;
2256 Lisp_Object lpath, element, tem;
2257
2258 /* It's okay to use getenv here, because this function is only used
2259 to initialize variables when Emacs starts up, and isn't called
2260 after that. */
2261 if (evarname != 0)
2262 path = (char *) getenv (evarname);
2263 else
2264 path = 0;
2265 if (!path)
2266 path = defalt;
2267 #ifdef DOS_NT
2268 /* Ensure values from the environment use the proper directory separator. */
2269 if (path)
2270 {
2271 p = alloca (strlen (path) + 1);
2272 strcpy (p, path);
2273 path = p;
2274
2275 if ('/' == DIRECTORY_SEP)
2276 dostounix_filename (path);
2277 else
2278 unixtodos_filename (path);
2279 }
2280 #endif
2281 lpath = Qnil;
2282 while (1)
2283 {
2284 p = index (path, SEPCHAR);
2285 if (!p) p = path + strlen (path);
2286 element = (p - path ? make_string (path, p - path)
2287 : build_string ("."));
2288
2289 /* Add /: to the front of the name
2290 if it would otherwise be treated as magic. */
2291 tem = Ffind_file_name_handler (element, Qt);
2292
2293 /* However, if the handler says "I'm safe",
2294 don't bother adding /:. */
2295 if (SYMBOLP (tem))
2296 {
2297 Lisp_Object prop;
2298 prop = Fget (tem, intern ("safe-magic"));
2299 if (! NILP (prop))
2300 tem = Qnil;
2301 }
2302
2303 if (! NILP (tem))
2304 element = concat2 (build_string ("/:"), element);
2305
2306 lpath = Fcons (element, lpath);
2307 if (*p)
2308 path = p + 1;
2309 else
2310 break;
2311 }
2312 return Fnreverse (lpath);
2313 }
2314
2315 void
2316 syms_of_emacs ()
2317 {
2318 Qfile_name_handler_alist = intern ("file-name-handler-alist");
2319 staticpro (&Qfile_name_handler_alist);
2320
2321 #ifndef CANNOT_DUMP
2322 #ifdef HAVE_SHM
2323 defsubr (&Sdump_emacs_data);
2324 #else
2325 defsubr (&Sdump_emacs);
2326 #endif
2327 #endif
2328
2329 defsubr (&Skill_emacs);
2330
2331 defsubr (&Sinvocation_name);
2332 defsubr (&Sinvocation_directory);
2333
2334 DEFVAR_LISP ("command-line-args", &Vcommand_line_args,
2335 doc: /* Args passed by shell to Emacs, as a list of strings.
2336 Many arguments are deleted from the list as they are processed. */);
2337
2338 DEFVAR_LISP ("system-type", &Vsystem_type,
2339 doc: /* Value is symbol indicating type of operating system you are using. */);
2340 Vsystem_type = intern (SYSTEM_TYPE);
2341
2342 DEFVAR_LISP ("system-configuration", &Vsystem_configuration,
2343 doc: /* Value is string indicating configuration Emacs was built for.
2344 On MS-Windows, the value reflects the OS flavor and version on which
2345 Emacs is running. */);
2346 Vsystem_configuration = build_string (EMACS_CONFIGURATION);
2347
2348 DEFVAR_LISP ("system-configuration-options", &Vsystem_configuration_options,
2349 doc: /* String containing the configuration options Emacs was built with. */);
2350 Vsystem_configuration_options = build_string (EMACS_CONFIG_OPTIONS);
2351
2352 DEFVAR_BOOL ("noninteractive", &noninteractive1,
2353 doc: /* Non-nil means Emacs is running without interactive terminal. */);
2354
2355 DEFVAR_LISP ("kill-emacs-hook", &Vkill_emacs_hook,
2356 doc: /* Hook to be run when kill-emacs is called.
2357 Since `kill-emacs' may be invoked when the terminal is disconnected (or
2358 in other similar situations), functions placed on this hook should not
2359 expect to be able to interact with the user. To ask for confirmation,
2360 see `kill-emacs-query-functions' instead.
2361
2362 The hook is not run in batch mode, i.e., if `noninteractive' is non-nil. */);
2363 Vkill_emacs_hook = Qnil;
2364
2365 empty_string = build_string ("");
2366 staticpro (&empty_string);
2367
2368 #ifdef SIGUSR1
2369 DEFVAR_LISP ("signal-USR1-hook", &Vsignal_USR1_hook,
2370 doc: /* Hook to be run whenever emacs receives a USR1 signal. */);
2371 Vsignal_USR1_hook = Qnil;
2372 #ifdef SIGUSR2
2373 DEFVAR_LISP ("signal-USR2-hook", &Vsignal_USR2_hook,
2374 doc: /* Hook to be run whenever emacs receives a USR2 signal. */);
2375 Vsignal_USR2_hook = Qnil;
2376 #endif
2377 #endif
2378
2379
2380 DEFVAR_INT ("emacs-priority", &emacs_priority,
2381 doc: /* Priority for Emacs to run at.
2382 This value is effective only if set before Emacs is dumped,
2383 and only if the Emacs executable is installed with setuid to permit
2384 it to change priority. (Emacs sets its uid back to the real uid.)
2385 Currently, you need to define SET_EMACS_PRIORITY in `config.h'
2386 before you compile Emacs, to enable the code for this feature. */);
2387 emacs_priority = 0;
2388
2389 DEFVAR_LISP ("path-separator", &Vpath_separator,
2390 doc: /* The directory separator in search paths, as a string. */);
2391 {
2392 char c = SEPCHAR;
2393 Vpath_separator = make_string (&c, 1);
2394 }
2395
2396 DEFVAR_LISP ("invocation-name", &Vinvocation_name,
2397 doc: /* The program name that was used to run Emacs.
2398 Any directory names are omitted. */);
2399
2400 DEFVAR_LISP ("invocation-directory", &Vinvocation_directory,
2401 doc: /* The directory in which the Emacs executable was found, to run it.
2402 The value is nil if that directory's name is not known. */);
2403
2404 DEFVAR_LISP ("installation-directory", &Vinstallation_directory,
2405 doc: /* A directory within which to look for the `lib-src' and `etc' directories.
2406 This is non-nil when we can't find those directories in their standard
2407 installed locations, but we can find them
2408 near where the Emacs executable was found. */);
2409 Vinstallation_directory = Qnil;
2410
2411 DEFVAR_LISP ("system-messages-locale", &Vsystem_messages_locale,
2412 doc: /* System locale for messages. */);
2413 Vsystem_messages_locale = Qnil;
2414
2415 DEFVAR_LISP ("previous-system-messages-locale",
2416 &Vprevious_system_messages_locale,
2417 doc: /* Most recently used system locale for messages. */);
2418 Vprevious_system_messages_locale = Qnil;
2419
2420 DEFVAR_LISP ("system-time-locale", &Vsystem_time_locale,
2421 doc: /* System locale for time. */);
2422 Vsystem_time_locale = Qnil;
2423
2424 DEFVAR_LISP ("previous-system-time-locale", &Vprevious_system_time_locale,
2425 doc: /* Most recently used system locale for time. */);
2426 Vprevious_system_time_locale = Qnil;
2427 }
2428
2429 /* arch-tag: 7bfd356a-c720-4612-8ab6-aa4222931c2e
2430 (do not change this comment) */