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