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