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