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