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