]> code.delx.au - gnu-emacs/blob - src/emacs.c
(main): Fix args to handle `--display DISPLAY'.
[gnu-emacs] / src / emacs.c
1 /* Fully extensible Emacs, running on Unix, intended for GNU.
2 Copyright (C) 1985, 86, 87, 93, 94, 95 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21 #include <signal.h>
22 #include <errno.h>
23
24 #include <config.h>
25 #include <stdio.h>
26
27 #include <sys/types.h>
28 #include <sys/file.h>
29
30 #ifdef VMS
31 #include <ssdef.h>
32 #endif
33
34 #ifdef BSD
35 #include <sys/ioctl.h>
36 #endif
37
38 #include "lisp.h"
39 #include "commands.h"
40 #include "intervals.h"
41
42 #include "systty.h"
43 #include "syssignal.h"
44 #include "process.h"
45
46 #ifndef O_RDWR
47 #define O_RDWR 2
48 #endif
49
50 extern void malloc_warning ();
51 extern char *index ();
52 extern char *strerror ();
53
54 /* Command line args from shell, as list of strings */
55 Lisp_Object Vcommand_line_args;
56
57 /* The name under which Emacs was invoked, with any leading directory
58 names discarded. */
59 Lisp_Object Vinvocation_name;
60
61 /* The directory name from which Emacs was invoked. */
62 Lisp_Object Vinvocation_directory;
63
64 /* The directory name in which to find subdirs such as lisp and etc.
65 nil means get them only from PATH_LOADSEARCH. */
66 Lisp_Object Vinstallation_directory;
67
68 /* Hook run by `kill-emacs' before it does really anything. */
69 Lisp_Object Vkill_emacs_hook;
70
71 /* Set nonzero after Emacs has started up the first time.
72 Prevents reinitialization of the Lisp world and keymaps
73 on subsequent starts. */
74 int initialized;
75
76 /* Variable whose value is symbol giving operating system type. */
77 Lisp_Object Vsystem_type;
78
79 /* Variable whose value is string giving configuration built for. */
80 Lisp_Object Vsystem_configuration;
81
82 /* Variable whose value is string giving configuration options,
83 for use when reporting bugs. */
84 Lisp_Object Vsystem_configuration_options;
85
86 /* If non-zero, emacs should not attempt to use an window-specific code,
87 but instead should use the virtual terminal under which it was started */
88 int inhibit_window_system;
89
90 /* If nonzero, set Emacs to run at this priority. This is also used
91 in child_setup and sys_suspend to make sure subshells run at normal
92 priority; Those functions have their own extern declaration. */
93 int emacs_priority;
94
95 /* If non-zero a filter or a sentinel is running. Tested to save the match
96 data on the first attempt to change it inside asynchronous code. */
97 int running_asynch_code;
98
99 #ifdef BSD_PGRPS
100 /* See sysdep.c. */
101 extern int inherited_pgroup;
102 #endif
103
104 #ifdef HAVE_X_WINDOWS
105 /* If non-zero, -d was specified, meaning we're using some window system. */
106 int display_arg;
107 #endif
108
109 /* An address near the bottom of the stack.
110 Tells GC how to save a copy of the stack. */
111 char *stack_bottom;
112
113 #ifdef HAVE_WINDOW_SYSTEM
114 extern Lisp_Object Vwindow_system;
115 #endif /* HAVE_WINDOW_SYSTEM */
116
117 extern Lisp_Object Vauto_save_list_file_name;
118
119 #ifdef USG_SHARED_LIBRARIES
120 /* If nonzero, this is the place to put the end of the writable segment
121 at startup. */
122
123 unsigned int bss_end = 0;
124 #endif
125
126 /* Nonzero means running Emacs without interactive terminal. */
127
128 int noninteractive;
129
130 /* Value of Lisp variable `noninteractive'.
131 Normally same as C variable `noninteractive'
132 but nothing terrible happens if user sets this one. */
133
134 int noninteractive1;
135
136 /* Save argv and argc. */
137 char **initial_argv;
138 int initial_argc;
139
140 static void sort_args ();
141 \f
142 /* Signal code for the fatal signal that was received */
143 int fatal_error_code;
144
145 /* Nonzero if handling a fatal error already */
146 int fatal_error_in_progress;
147
148 /* Handle bus errors, illegal instruction, etc. */
149 SIGTYPE
150 fatal_error_signal (sig)
151 int sig;
152 {
153 fatal_error_code = sig;
154 signal (sig, SIG_DFL);
155
156 /* If fatal error occurs in code below, avoid infinite recursion. */
157 if (! fatal_error_in_progress)
158 {
159 fatal_error_in_progress = 1;
160
161 shut_down_emacs (sig, 0, Qnil);
162 }
163
164 #ifdef VMS
165 LIB$STOP (SS$_ABORT);
166 #else
167 /* Signal the same code; this time it will really be fatal.
168 Remember that since we're in a signal handler, the signal we're
169 going to send is probably blocked, so we have to unblock it if we
170 want to really receive it. */
171 #ifndef MSDOS
172 sigunblock (sigmask (fatal_error_code));
173 #endif
174 kill (getpid (), fatal_error_code);
175 #endif /* not VMS */
176 }
177
178 #ifdef SIGDANGER
179
180 /* Handler for SIGDANGER. */
181 SIGTYPE
182 memory_warning_signal (sig)
183 int sig;
184 {
185 signal (sig, memory_warning_signal);
186
187 malloc_warning ("Operating system warns that virtual memory is running low.\n");
188
189 /* It might be unsafe to call do_auto_save now. */
190 force_auto_save_soon ();
191 }
192 #endif
193 \f
194 /* Code for dealing with Lisp access to the Unix command line */
195
196 static
197 init_cmdargs (argc, argv, skip_args)
198 int argc;
199 char **argv;
200 int skip_args;
201 {
202 register int i;
203 Lisp_Object name, dir;
204
205 initial_argv = argv;
206 initial_argc = argc;
207
208 Vinvocation_name = Ffile_name_nondirectory (build_string (argv[0]));
209 Vinvocation_directory = Ffile_name_directory (build_string (argv[0]));
210 /* If we got no directory in argv[0], search PATH to find where
211 Emacs actually came from. */
212 if (NILP (Vinvocation_directory))
213 {
214 Lisp_Object found;
215 int yes = openp (Vexec_path, Vinvocation_name,
216 EXEC_SUFFIXES, &found, 1);
217 if (yes == 1)
218 Vinvocation_directory = Ffile_name_directory (found);
219 }
220
221 if (!NILP (Vinvocation_directory)
222 && NILP (Ffile_name_absolute_p (Vinvocation_directory)))
223 /* Emacs was started with relative path, like ./emacs */
224 Vinvocation_directory = Fexpand_file_name (Vinvocation_directory, Qnil);
225
226 Vinstallation_directory = Qnil;
227
228 if (!NILP (Vinvocation_directory))
229 {
230 dir = Vinvocation_directory;
231 name = Fexpand_file_name (Vinvocation_name, dir);
232 while (1)
233 {
234 Lisp_Object tem, lib_src_exists;
235 Lisp_Object etc_exists, info_exists;
236
237 /* See if dir contains subdirs for use by Emacs.
238 Check for the ones that would exist in a build directory,
239 not including lisp and info. */
240 tem = Fexpand_file_name (build_string ("lib-src"), dir);
241 lib_src_exists = Ffile_exists_p (tem);
242 if (!NILP (lib_src_exists))
243 {
244 tem = Fexpand_file_name (build_string ("etc"), dir);
245 etc_exists = Ffile_exists_p (tem);
246 if (!NILP (etc_exists))
247 {
248 Vinstallation_directory
249 = Ffile_name_as_directory (dir);
250 break;
251 }
252 }
253
254 /* See if dir's parent contains those subdirs. */
255 tem = Fexpand_file_name (build_string ("../lib-src"), dir);
256 lib_src_exists = Ffile_exists_p (tem);
257 if (!NILP (lib_src_exists))
258 {
259 tem = Fexpand_file_name (build_string ("../etc"), dir);
260 etc_exists = Ffile_exists_p (tem);
261 if (!NILP (etc_exists))
262 {
263 tem = Fexpand_file_name (build_string (".."), dir);
264 Vinstallation_directory
265 = Ffile_name_as_directory (tem);
266 break;
267 }
268 }
269
270 /* If the Emacs executable is actually a link,
271 next try the dir that the link points into. */
272 tem = Ffile_symlink_p (name);
273 if (!NILP (tem))
274 {
275 name = Fexpand_file_name (tem, dir);
276 dir = Ffile_name_directory (name);
277 }
278 else
279 break;
280 }
281 }
282
283 Vcommand_line_args = Qnil;
284
285 for (i = argc - 1; i >= 0; i--)
286 {
287 if (i == 0 || i > skip_args)
288 Vcommand_line_args
289 = Fcons (build_string (argv[i]), Vcommand_line_args);
290 }
291 }
292
293 DEFUN ("invocation-name", Finvocation_name, Sinvocation_name, 0, 0, 0,
294 "Return the program name that was used to run Emacs.\n\
295 Any directory names are omitted.")
296 ()
297 {
298 return Fcopy_sequence (Vinvocation_name);
299 }
300
301 DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory,
302 0, 0, 0,
303 "Return the directory name in which the Emacs executable was located")
304 ()
305 {
306 return Fcopy_sequence (Vinvocation_directory);
307 }
308
309 \f
310 #ifdef VMS
311 #ifdef LINK_CRTL_SHARE
312 #ifdef SHAREABLE_LIB_BUG
313 extern noshare char **environ;
314 #endif /* SHAREABLE_LIB_BUG */
315 #endif /* LINK_CRTL_SHARE */
316 #endif /* VMS */
317
318 #ifndef ORDINARY_LINK
319 /* We don't include crtbegin.o and crtend.o in the link,
320 so these functions and variables might be missed.
321 Provide dummy definitions to avoid error.
322 (We don't have any real constructors or destructors.) */
323 #ifdef __GNUC__
324 #ifndef GCC_CTORS_IN_LIBC
325 __do_global_ctors ()
326 {}
327 __do_global_ctors_aux ()
328 {}
329 __do_global_dtors ()
330 {}
331 /* Linux has a bug in its library; avoid an error. */
332 #ifndef LINUX
333 char * __CTOR_LIST__[2] = { (char *) (-1), 0 };
334 #endif
335 char * __DTOR_LIST__[2] = { (char *) (-1), 0 };
336 #endif /* GCC_CTORS_IN_LIBC */
337 __main ()
338 {}
339 #endif /* __GNUC__ */
340 #endif /* ORDINARY_LINK */
341
342 /* Test whether the next argument in ARGV matches SSTR or a prefix of
343 LSTR (at least MINLEN characters). If so, then if VALPTR is non-null
344 (the argument is supposed to have a value) store in *VALPTR either
345 the next argument or the portion of this one after the equal sign.
346 ARGV is read starting at position *SKIPPTR; this index is advanced
347 by the number of arguments used.
348
349 Too bad we can't just use getopt for all of this, but we don't have
350 enough information to do it right. */
351
352 static int
353 argmatch (argv, argc, sstr, lstr, minlen, valptr, skipptr)
354 char **argv;
355 int argc;
356 char *sstr;
357 char *lstr;
358 int minlen;
359 char **valptr;
360 int *skipptr;
361 {
362 char *p;
363 int arglen;
364 char *arg;
365
366 /* Don't access argv[argc]; give up in advance. */
367 if (argc <= *skipptr + 1)
368 return 0;
369
370 arg = argv[*skipptr+1];
371 if (arg == NULL)
372 return 0;
373 if (strcmp (arg, sstr) == 0)
374 {
375 if (valptr != NULL)
376 {
377 *valptr = argv[*skipptr+2];
378 *skipptr += 2;
379 }
380 else
381 *skipptr += 1;
382 return 1;
383 }
384 arglen = (valptr != NULL && (p = index (arg, '=')) != NULL
385 ? p - arg : strlen (arg));
386 if (lstr == 0 || arglen < minlen || strncmp (arg, lstr, arglen) != 0)
387 return 0;
388 else if (valptr == NULL)
389 {
390 *skipptr += 1;
391 return 1;
392 }
393 else if (p != NULL)
394 {
395 *valptr = p+1;
396 *skipptr += 1;
397 return 1;
398 }
399 else if (argv[*skipptr+2] != NULL)
400 {
401 *valptr = argv[*skipptr+2];
402 *skipptr += 2;
403 return 1;
404 }
405 else
406 {
407 return 0;
408 }
409 }
410
411 /* ARGSUSED */
412 main (argc, argv, envp)
413 int argc;
414 char **argv;
415 char **envp;
416 {
417 char stack_bottom_variable;
418 int skip_args = 0;
419 extern int errno;
420 extern sys_nerr;
421
422 #ifdef LINUX_SBRK_BUG
423 __sbrk (1);
424 #endif
425
426 sort_args (argc, argv);
427
428 if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args))
429 {
430 Lisp_Object tem;
431 tem = Fsymbol_value (intern ("emacs-version"));
432 if (!STRINGP (tem))
433 {
434 fprintf (stderr, "Invalid value of `emacs-version'\n");
435 exit (1);
436 }
437 else
438 {
439 printf ("%s\n", XSTRING (tem)->data);
440 exit (0);
441 }
442 }
443
444 /* Map in shared memory, if we are using that. */
445 #ifdef HAVE_SHM
446 if (argmatch (argv, argc, "-nl", "--no-shared-memory", 6, NULL, &skip_args))
447 {
448 map_in_data (0);
449 /* The shared memory was just restored, which clobbered this. */
450 skip_args = 1;
451 }
452 else
453 {
454 map_in_data (1);
455 /* The shared memory was just restored, which clobbered this. */
456 skip_args = 0;
457 }
458 #endif
459
460 #ifdef NeXT
461 {
462 extern int malloc_cookie;
463 /* This helps out unexnext.c. */
464 if (initialized)
465 if (malloc_jumpstart (malloc_cookie) != 0)
466 printf ("malloc jumpstart failed!\n");
467 }
468 #endif /* NeXT */
469
470 #ifdef VMS
471 /* If -map specified, map the data file in */
472 {
473 char *file;
474 if (argmatch (argv, argc, "-map", "--map-data", 3, &mapin_file, &skip_args))
475 mapin_data (file);
476 }
477
478 #ifdef LINK_CRTL_SHARE
479 #ifdef SHAREABLE_LIB_BUG
480 /* Bletcherous shared libraries! */
481 if (!stdin)
482 stdin = fdopen (0, "r");
483 if (!stdout)
484 stdout = fdopen (1, "w");
485 if (!stderr)
486 stderr = fdopen (2, "w");
487 if (!environ)
488 environ = envp;
489 #endif /* SHAREABLE_LIB_BUG */
490 #endif /* LINK_CRTL_SHARE */
491 #endif /* VMS */
492
493 /* Record (approximately) where the stack begins. */
494 stack_bottom = &stack_bottom_variable;
495
496 #ifdef RUN_TIME_REMAP
497 if (initialized)
498 run_time_remap (argv[0]);
499 #endif
500
501 #ifdef USG_SHARED_LIBRARIES
502 if (bss_end)
503 brk ((void *)bss_end);
504 #endif
505
506 clearerr (stdin);
507
508 #ifndef SYSTEM_MALLOC
509 if (! initialized)
510 {
511 /* Arrange to get warning messages as memory fills up. */
512 memory_warnings (0, malloc_warning);
513
514 /* Arrange to disable interrupt input while malloc and friends are
515 running. */
516 uninterrupt_malloc ();
517 }
518 #endif /* not SYSTEM_MALLOC */
519
520 #ifdef MSDOS
521 /* We do all file input/output as binary files. When we need to translate
522 newlines, we do that manually. */
523 _fmode = O_BINARY;
524 (stdin)->_flag &= ~_IOTEXT;
525 (stdout)->_flag &= ~_IOTEXT;
526 (stderr)->_flag &= ~_IOTEXT;
527 #endif /* MSDOS */
528
529 #ifdef SET_EMACS_PRIORITY
530 if (emacs_priority)
531 nice (emacs_priority);
532 setuid (getuid ());
533 #endif /* SET_EMACS_PRIORITY */
534
535 #ifdef EXTRA_INITIALIZE
536 EXTRA_INITIALIZE;
537 #endif
538
539 inhibit_window_system = 0;
540
541 /* Handle the -t switch, which specifies filename to use as terminal */
542 {
543 char *term;
544 if (argmatch (argv, argc, "-t", "--terminal", 4, &term, &skip_args))
545 {
546 int result;
547 close (0);
548 close (1);
549 result = open (term, O_RDWR, 2 );
550 if (result < 0)
551 {
552 char *errstring = strerror (errno);
553 fprintf (stderr, "emacs: %s: %s\n", term, errstring);
554 exit (1);
555 }
556 dup (0);
557 if (! isatty (0))
558 {
559 fprintf (stderr, "emacs: %s: not a tty\n", term);
560 exit (1);
561 }
562 fprintf (stderr, "Using %s\n", term);
563 #ifdef HAVE_WINDOW_SYSTEM
564 inhibit_window_system = 1; /* -t => -nw */
565 #endif
566 }
567 }
568 if (argmatch (argv, argc, "-nw", "--no-windows", 6, NULL, &skip_args))
569 inhibit_window_system = 1;
570
571 /* Handle the -batch switch, which means don't do interactive display. */
572 noninteractive = 0;
573 if (argmatch (argv, argc, "-batch", "--batch", 5, NULL, &skip_args))
574 noninteractive = 1;
575
576 /* Handle the --help option, which gives a usage message.. */
577 if (argmatch (argv, argc, "-help", "--help", 3, NULL, &skip_args))
578 {
579 printf ("\
580 Usage: %s [-t term] [--terminal term] [-nw] [--no-windows] [--batch]\n\
581 [-q] [--no-init-file] [-u user] [--user user] [--debug-init]\n\
582 [--version] [--no-site-file]\n\
583 [-f func] [--funcall func] [-l file] [--load file] [--insert file]\n\
584 [+linenum] file-to-visit [--kill]\n", argv[0]);
585 exit (0);
586 }
587
588 #ifdef HAVE_X_WINDOWS
589 /* Stupid kludge to catch command-line display spec. We can't
590 handle this argument entirely in window system dependent code
591 because we don't even know which window system dependent code
592 to run until we've recognized this argument. */
593 {
594 char *displayname;
595 int i;
596 int count_before = skip_args;
597
598 if (argmatch (argv, argc, "-d", "--display", 3, &displayname, &skip_args))
599 display_arg = 1;
600 else if (argmatch (argv, argc, "-display", 0, 3, &displayname, &skip_args))
601 display_arg = 1;
602
603 /* If we have the form --display=NAME,
604 convert it into -d name.
605 This requires inserting a new element into argv. */
606 if (displayname != 0 && skip_args - count_before == 1)
607 {
608 char **new = (char **) xmalloc (sizeof (char *) * (argc + 2));
609 int j;
610
611 for (j = 0; j < count_before + 1; j++)
612 new[j] = argv[j];
613 new[count_before + 1] = "-d";
614 new[count_before + 2] = displayname;
615 for (j = count_before + 2; j <argc; j++)
616 new[j + 1] = argv[j];
617 argv = new;
618 argc++;
619 }
620 /* Change --display to -d, when its arg is separate. */
621 else if (displayname != 0 && skip_args > count_before
622 && argv[count_before + 1][1] == '-')
623 argv[count_before + 1] = "-d";
624
625 /* Don't actually discard this arg. */
626 skip_args = count_before;
627 }
628 #endif
629
630 if (! noninteractive)
631 {
632 #ifdef BSD_PGRPS
633 if (initialized)
634 {
635 inherited_pgroup = EMACS_GETPGRP (0);
636 setpgrp (0, getpid ());
637 }
638 #else
639 #if defined (USG5) && defined (INTERRUPT_INPUT)
640 setpgrp ();
641 #endif
642 #endif
643 }
644
645 #ifdef POSIX_SIGNALS
646 init_signals ();
647 #endif
648
649 if (
650 #ifndef CANNOT_DUMP
651 ! noninteractive || initialized
652 #else
653 1
654 #endif
655 )
656 {
657 /* Don't catch these signals in batch mode if not initialized.
658 On some machines, this sets static data that would make
659 signal fail to work right when the dumped Emacs is run. */
660 signal (SIGHUP, fatal_error_signal);
661 signal (SIGQUIT, fatal_error_signal);
662 signal (SIGILL, fatal_error_signal);
663 signal (SIGTRAP, fatal_error_signal);
664 #ifdef SIGABRT
665 signal (SIGABRT, fatal_error_signal);
666 #endif
667 #ifdef SIGHWE
668 signal (SIGHWE, fatal_error_signal);
669 #endif
670 #ifdef SIGPRE
671 signal (SIGPRE, fatal_error_signal);
672 #endif
673 #ifdef SIGORE
674 signal (SIGORE, fatal_error_signal);
675 #endif
676 #ifdef SIGUME
677 signal (SIGUME, fatal_error_signal);
678 #endif
679 #ifdef SIGDLK
680 signal (SIGDLK, fatal_error_signal);
681 #endif
682 #ifdef SIGCPULIM
683 signal (SIGCPULIM, fatal_error_signal);
684 #endif
685 #ifdef SIGIOT
686 /* This is missing on some systems - OS/2, for example. */
687 signal (SIGIOT, fatal_error_signal);
688 #endif
689 #ifdef SIGEMT
690 signal (SIGEMT, fatal_error_signal);
691 #endif
692 signal (SIGFPE, fatal_error_signal);
693 #ifdef SIGBUS
694 signal (SIGBUS, fatal_error_signal);
695 #endif
696 signal (SIGSEGV, fatal_error_signal);
697 #ifdef SIGSYS
698 signal (SIGSYS, fatal_error_signal);
699 #endif
700 signal (SIGTERM, fatal_error_signal);
701 #ifdef SIGXCPU
702 signal (SIGXCPU, fatal_error_signal);
703 #endif
704 #ifdef SIGXFSZ
705 signal (SIGXFSZ, fatal_error_signal);
706 #endif /* SIGXFSZ */
707
708 #ifdef SIGDANGER
709 /* This just means available memory is getting low. */
710 signal (SIGDANGER, memory_warning_signal);
711 #endif
712
713 #ifdef AIX
714 /* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */
715 signal (SIGXCPU, fatal_error_signal);
716 #ifndef _I386
717 signal (SIGIOINT, fatal_error_signal);
718 #endif
719 signal (SIGGRANT, fatal_error_signal);
720 signal (SIGRETRACT, fatal_error_signal);
721 signal (SIGSOUND, fatal_error_signal);
722 signal (SIGMSG, fatal_error_signal);
723 #endif /* AIX */
724 }
725
726 noninteractive1 = noninteractive;
727
728 /* Perform basic initializations (not merely interning symbols) */
729
730 if (!initialized)
731 {
732 init_alloc_once ();
733 init_obarray ();
734 init_eval_once ();
735 init_syntax_once (); /* Create standard syntax table. */
736 /* Must be done before init_buffer */
737 init_casetab_once ();
738 init_buffer_once (); /* Create buffer table and some buffers */
739 init_minibuf_once (); /* Create list of minibuffers */
740 /* Must precede init_window_once */
741 init_window_once (); /* Init the window system */
742 }
743
744 init_alloc ();
745 init_eval ();
746 init_data ();
747 running_asynch_code = 0;
748
749 #ifdef MSDOS
750 /* Call early 'cause init_environment needs it. */
751 init_dosfns ();
752 /* Set defaults for several environment variables. */
753 if (initialized) init_environment (argc, argv, skip_args);
754 else init_gettimeofday ();
755 #endif
756
757 #ifdef WINDOWSNT
758 /* Initialize environment from registry settings. */
759 init_environment ();
760 #endif
761
762 /* egetenv is a pretty low-level facility, which may get called in
763 many circumstances; it seems flimsy to put off initializing it
764 until calling init_callproc. */
765 set_process_environment ();
766 /* AIX crashes are reported in system versions 3.2.3 and 3.2.4
767 if this is not done. Do it after set_process_environment so that we
768 don't pollute Vprocess_environment. */
769 #ifdef AIX
770 putenv ("LANG=C");
771 #endif
772
773 init_buffer (); /* Init default directory of main buffer */
774
775 init_callproc_1 (); /* Must precede init_cmdargs and init_sys_modes. */
776 init_cmdargs (argc, argv, skip_args); /* Must precede init_lread. */
777 init_callproc (); /* Must follow init_cmdargs but not init_sys_modes. */
778 init_lread ();
779
780 if (!noninteractive)
781 {
782 #ifdef VMS
783 init_vms_input ();/* init_display calls get_frame_size, that needs this */
784 #endif /* VMS */
785 init_display (); /* Determine terminal type. init_sys_modes uses results */
786 }
787 init_keyboard (); /* This too must precede init_sys_modes */
788 #ifdef VMS
789 init_vmsproc (); /* And this too. */
790 #endif /* VMS */
791 init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.) */
792 init_xdisp ();
793 init_macros ();
794 init_editfns ();
795 #ifdef LISP_FLOAT_TYPE
796 init_floatfns ();
797 #endif
798 #ifdef VMS
799 init_vmsfns ();
800 #endif /* VMS */
801 init_process ();
802 #ifdef CLASH_DETECTION
803 init_filelock ();
804 #endif /* CLASH_DETECTION */
805
806 /* Intern the names of all standard functions and variables; define standard keys */
807
808 if (!initialized)
809 {
810 /* The basic levels of Lisp must come first */
811 /* And data must come first of all
812 for the sake of symbols like error-message */
813 syms_of_data ();
814 syms_of_alloc ();
815 syms_of_lread ();
816 syms_of_print ();
817 syms_of_eval ();
818 syms_of_fns ();
819 syms_of_floatfns ();
820
821 syms_of_abbrev ();
822 syms_of_buffer ();
823 syms_of_bytecode ();
824 syms_of_callint ();
825 syms_of_casefiddle ();
826 syms_of_casetab ();
827 syms_of_callproc ();
828 syms_of_cmds ();
829 #ifndef NO_DIR_LIBRARY
830 syms_of_dired ();
831 #endif /* not NO_DIR_LIBRARY */
832 syms_of_display ();
833 syms_of_doc ();
834 syms_of_editfns ();
835 syms_of_emacs ();
836 syms_of_fileio ();
837 #ifdef CLASH_DETECTION
838 syms_of_filelock ();
839 #endif /* CLASH_DETECTION */
840 syms_of_indent ();
841 syms_of_keyboard ();
842 syms_of_keymap ();
843 syms_of_macros ();
844 syms_of_marker ();
845 syms_of_minibuf ();
846 syms_of_mocklisp ();
847 syms_of_process ();
848 syms_of_search ();
849 syms_of_frame ();
850 syms_of_syntax ();
851 syms_of_term ();
852 syms_of_undo ();
853
854 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
855 syms_of_textprop ();
856 #ifdef VMS
857 syms_of_vmsproc ();
858 #endif /* VMS */
859 syms_of_window ();
860 syms_of_xdisp ();
861 #ifdef HAVE_X_WINDOWS
862 syms_of_xterm ();
863 syms_of_xfns ();
864 syms_of_xfaces ();
865 #ifdef HAVE_X11
866 syms_of_xselect ();
867 #endif
868 #ifdef HAVE_X_MENU
869 syms_of_xmenu ();
870 #endif /* HAVE_X_MENU */
871 #endif /* HAVE_X_WINDOWS */
872
873 #if defined (MSDOS) && !defined (HAVE_X_WINDOWS)
874 syms_of_xfaces ();
875 syms_of_xmenu ();
876 #endif
877
878 #ifdef HAVE_NTGUI
879 syms_of_win32term ();
880 syms_of_win32fns ();
881 syms_of_win32faces ();
882 syms_of_win32select ();
883 syms_of_win32menu ();
884 #endif /* HAVE_NTGUI */
885
886 #ifdef SYMS_SYSTEM
887 SYMS_SYSTEM;
888 #endif
889
890 #ifdef SYMS_MACHINE
891 SYMS_MACHINE;
892 #endif
893
894 keys_of_casefiddle ();
895 keys_of_cmds ();
896 keys_of_buffer ();
897 keys_of_keyboard ();
898 keys_of_keymap ();
899 keys_of_macros ();
900 keys_of_minibuf ();
901 keys_of_window ();
902 keys_of_frame ();
903 }
904
905 if (!initialized)
906 {
907 char *file;
908 /* Handle -l loadup-and-dump, args passed by Makefile. */
909 if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args))
910 Vtop_level = Fcons (intern ("load"),
911 Fcons (build_string (file), Qnil));
912 #ifdef CANNOT_DUMP
913 /* Unless next switch is -nl, load "loadup.el" first thing. */
914 if (!argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args))
915 Vtop_level = Fcons (intern ("load"),
916 Fcons (build_string ("loadup.el"), Qnil));
917 #endif /* CANNOT_DUMP */
918 }
919
920 if (initialized)
921 {
922 /* Erase any pre-dump messages in the message log, to avoid confusion */
923 Lisp_Object old_log_max;
924 old_log_max = Vmessage_log_max;
925 XSETFASTINT (Vmessage_log_max, 0);
926 message_dolog ("", 0, 1);
927 Vmessage_log_max = old_log_max;
928 }
929
930 initialized = 1;
931
932 #ifdef LOCALTIME_CACHE
933 /* Some versions of localtime have a bug. They cache the value of the time
934 zone rather than looking it up every time. Since localtime() is
935 called to bolt the undumping time into the undumped emacs, this
936 results in localtime ignoring the TZ environment variable.
937 This flushes the new TZ value into localtime. */
938 tzset ();
939 #endif /* defined (LOCALTIME_CACHE) */
940
941 /* Enter editor command loop. This never returns. */
942 Frecursive_edit ();
943 /* NOTREACHED */
944 }
945 \f
946 /* Sort the args so we can find the most important ones
947 at the beginning of argv. */
948
949 /* First, here's a table of all the standard options. */
950
951 struct standard_args
952 {
953 char *name;
954 char *longname;
955 int priority;
956 int nargs;
957 };
958
959 struct standard_args standard_args[] =
960 {
961 { "-version", "--version", 110, 0 },
962 { "-help", "--help", 110, 0 },
963 { "-nl", "--no-shared-memory", 100, 0 },
964 #ifdef VMS
965 { "-map", "--map-data", 100, 0 },
966 #endif
967 { "-t", "--terminal", 90, 1 },
968 { "-d", "--display", 80, 1 },
969 { "-display", 0, 80, 1 },
970 { "-nw", "--no-windows", 70, 0 },
971 { "-batch", "--batch", 60, 0 },
972 { "-q", "--no-init-file", 50, 0 },
973 { "-no-init-file", 0, 50, 0 },
974 { "-no-site-file", "--no-site-file", 40, 0 },
975 { "-u", "--user", 30, 1 },
976 { "-user", 0, 30, 1 },
977 { "-debug-init", "--debug-init", 20, 0 },
978 { "-i", "--icon-type", 15, 0 },
979 { "-itype", 0, 15, 0 },
980 { "-iconic", "--iconic", 15, 0 },
981 { "-bg", "--background-color", 10, 1 },
982 { "-background", 0, 10, 1 },
983 { "-fg", "--foreground-color", 10, 1 },
984 { "-foreground", 0, 10, 1 },
985 { "-bd", "--border-color", 10, 1 },
986 { "-bw", "--border-width", 10, 1 },
987 { "-ib", "--internal-border", 10, 1 },
988 { "-ms", "--mouse-color", 10, 1 },
989 { "-cr", "--cursor-color", 10, 1 },
990 { "-fn", "--font", 10, 1 },
991 { "-font", 0, 10, 1 },
992 { "-g", "--geometry", 10, 1 },
993 { "-geometry", 0, 10, 1 },
994 { "-T", "--title", 10, 1 },
995 { "-name", "--name", 10, 1 },
996 { "-xrm", "--xrm", 10, 1 },
997 { "-r", "--reverse-video", 5, 0 },
998 { "-rv", 0, 5, 0 },
999 { "-reverse", 0, 5, 0 },
1000 { "-vb", "--vertical-scroll-bars", 5, 0 },
1001 /* These have the same priority as ordinary file name args,
1002 so they are not reordered with respect to those. */
1003 { "-L", "--directory", 0, 1 },
1004 { "-directory", 0, 0, 1 },
1005 { "-l", "--load", 0, 1 },
1006 { "-load", 0, 0, 1 },
1007 { "-f", "--funcall", 0, 1 },
1008 { "-funcall", 0, 0, 1 },
1009 { "-eval", "--eval", 0, 1 },
1010 { "-insert", "--insert", 0, 1 },
1011 /* This should be processed after ordinary file name args and the like. */
1012 { "-kill", "--kill", -10, 0 },
1013 };
1014
1015 /* Reorder the elements of ARGV (assumed to have ARGC elements)
1016 so that the highest priority ones come first.
1017 Do not change the order of elements of equal priority.
1018 If an option takes an argument, keep it and its argument together. */
1019
1020 static void
1021 sort_args (argc, argv)
1022 int argc;
1023 char **argv;
1024 {
1025 char **new = (char **) xmalloc (sizeof (char *) * argc);
1026 /* For each element of argv,
1027 the corresponding element of options is:
1028 0 for an option that takes no arguments,
1029 1 for an option that takes one argument, etc.
1030 -1 for an ordinary non-option argument. */
1031 int *options = (int *) xmalloc (sizeof (int) * argc);
1032 int *priority = (int *) xmalloc (sizeof (int) * argc);
1033 int to = 1;
1034 int from;
1035 int i;
1036
1037 /* Categorize all the options,
1038 and figure out which argv elts are option arguments. */
1039 for (from = 1; from < argc; from++)
1040 {
1041 options[from] = -1;
1042 priority[from] = 0;
1043 if (argv[from][0] == '-')
1044 {
1045 int match, thislen;
1046 char *equals;
1047
1048 /* Look for a match with a known old-fashioned option. */
1049 for (i = 0; i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
1050 if (!strcmp (argv[from], standard_args[i].name))
1051 {
1052 options[from] = standard_args[i].nargs;
1053 priority[from] = standard_args[i].priority;
1054 from += standard_args[i].nargs;
1055 goto done;
1056 }
1057
1058 /* Look for a match with a known long option.
1059 MATCH is -1 if no match so far, -2 if two or more matches so far,
1060 >= 0 (the table index of the match) if just one match so far. */
1061 if (argv[from][1] == '-')
1062 {
1063 match = -1;
1064 thislen = strlen (argv[from]);
1065 equals = index (argv[from], '=');
1066 if (equals != 0)
1067 thislen = equals - argv[from];
1068
1069 for (i = 0;
1070 i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
1071 if (standard_args[i].longname
1072 && !strncmp (argv[from], standard_args[i].longname,
1073 thislen))
1074 {
1075 if (match == -1)
1076 match = i;
1077 else
1078 match = -2;
1079 }
1080
1081 /* If we found exactly one match, use that. */
1082 if (match >= 0)
1083 {
1084 options[from] = standard_args[match].nargs;
1085 priority[from] = standard_args[match].priority;
1086 /* If --OPTION=VALUE syntax is used,
1087 this option uses just one argv element. */
1088 if (equals != 0)
1089 options[from] = 0;
1090 from += options[from];
1091 }
1092 }
1093 done: ;
1094 }
1095 }
1096
1097 /* Copy the arguments, in order of decreasing priority, to NEW. */
1098 new[0] = argv[0];
1099 while (to < argc)
1100 {
1101 int best = -1;
1102 int best_priority = -9999;
1103
1104 /* Find the highest priority remaining option.
1105 If several have equal priority, take the first of them. */
1106 for (from = 1; from < argc; from++)
1107 {
1108 if (argv[from] != 0 && priority[from] > best_priority)
1109 {
1110 best_priority = priority[from];
1111 best = from;
1112 }
1113 /* Skip option arguments--they are tied to the options. */
1114 if (options[from] > 0)
1115 from += options[from];
1116 }
1117
1118 if (best < 0)
1119 abort ();
1120
1121 /* Copy the highest priority remaining option, with its args, to NEW. */
1122 new[to++] = argv[best];
1123 for (i = 0; i < options[best]; i++)
1124 new[to++] = argv[best + i + 1];
1125
1126 /* Clear out this option in ARGV. */
1127 argv[best] = 0;
1128 for (i = 0; i < options[best]; i++)
1129 argv[best + i + 1] = 0;
1130 }
1131
1132 bcopy (new, argv, sizeof (char *) * argc);
1133 }
1134 \f
1135 DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P",
1136 "Exit the Emacs job and kill it.\n\
1137 If ARG is an integer, return ARG as the exit program code.\n\
1138 If ARG is a string, stuff it as keyboard input.\n\n\
1139 The value of `kill-emacs-hook', if not void,\n\
1140 is a list of functions (of no args),\n\
1141 all of which are called before Emacs is actually killed.")
1142 (arg)
1143 Lisp_Object arg;
1144 {
1145 Lisp_Object hook, hook1;
1146 int i;
1147 struct gcpro gcpro1;
1148
1149 GCPRO1 (arg);
1150
1151 if (feof (stdin))
1152 arg = Qt;
1153
1154 if (!NILP (Vrun_hooks) && !noninteractive)
1155 call1 (Vrun_hooks, intern ("kill-emacs-hook"));
1156
1157 UNGCPRO;
1158
1159 /* Is it really necessary to do this deassign
1160 when we are going to exit anyway? */
1161 /* #ifdef VMS
1162 stop_vms_input ();
1163 #endif */
1164
1165 shut_down_emacs (0, 0, STRINGP (arg) ? arg : Qnil);
1166
1167 /* If we have an auto-save list file,
1168 kill it because we are exiting Emacs deliberately (not crashing).
1169 Do it after shut_down_emacs, which does an auto-save. */
1170 if (STRINGP (Vauto_save_list_file_name))
1171 unlink (XSTRING (Vauto_save_list_file_name)->data);
1172
1173 exit (INTEGERP (arg) ? XINT (arg)
1174 #ifdef VMS
1175 : 1
1176 #else
1177 : 0
1178 #endif
1179 );
1180 /* NOTREACHED */
1181 }
1182
1183
1184 /* Perform an orderly shutdown of Emacs. Autosave any modified
1185 buffers, kill any child processes, clean up the terminal modes (if
1186 we're in the foreground), and other stuff like that. Don't perform
1187 any redisplay; this may be called when Emacs is shutting down in
1188 the background, or after its X connection has died.
1189
1190 If SIG is a signal number, print a message for it.
1191
1192 This is called by fatal signal handlers, X protocol error handlers,
1193 and Fkill_emacs. */
1194
1195 void
1196 shut_down_emacs (sig, no_x, stuff)
1197 int sig, no_x;
1198 Lisp_Object stuff;
1199 {
1200 /* Prevent running of hooks from now on. */
1201 Vrun_hooks = Qnil;
1202
1203 /* If we are controlling the terminal, reset terminal modes */
1204 #ifdef EMACS_HAVE_TTY_PGRP
1205 {
1206 int pgrp = EMACS_GETPGRP (0);
1207
1208 int tpgrp;
1209 if (EMACS_GET_TTY_PGRP (0, &tpgrp) != -1
1210 && tpgrp == pgrp)
1211 {
1212 fflush (stdout);
1213 reset_sys_modes ();
1214 if (sig && sig != SIGTERM)
1215 fprintf (stderr, "Fatal error (%d).", sig);
1216 }
1217 }
1218 #else
1219 fflush (stdout);
1220 reset_sys_modes ();
1221 #endif
1222
1223 stuff_buffered_input (stuff);
1224
1225 kill_buffer_processes (Qnil);
1226 Fdo_auto_save (Qt, Qnil);
1227
1228 #ifdef CLASH_DETECTION
1229 unlock_all_files ();
1230 #endif
1231
1232 #ifdef VMS
1233 kill_vms_processes ();
1234 #endif
1235
1236 #if 0 /* This triggers a bug in XCloseDisplay and is not needed. */
1237 #ifdef HAVE_X_WINDOWS
1238 /* It's not safe to call intern here. Maybe we are crashing. */
1239 if (!noninteractive && SYMBOLP (Vwindow_system)
1240 && XSYMBOL (Vwindow_system)->name->size == 1
1241 && XSYMBOL (Vwindow_system)->name->data[0] == 'x'
1242 && ! no_x)
1243 Fx_close_current_connection ();
1244 #endif /* HAVE_X_WINDOWS */
1245 #endif
1246
1247 #ifdef SIGIO
1248 /* There is a tendency for a SIGIO signal to arrive within exit,
1249 and cause a SIGHUP because the input descriptor is already closed. */
1250 unrequest_sigio ();
1251 signal (SIGIO, SIG_IGN);
1252 #endif
1253 }
1254
1255
1256 \f
1257 #ifndef CANNOT_DUMP
1258
1259 #ifdef HAVE_SHM
1260
1261 DEFUN ("dump-emacs-data", Fdump_emacs_data, Sdump_emacs_data, 1, 1, 0,
1262 "Dump current state of Emacs into data file FILENAME.\n\
1263 This function exists on systems that use HAVE_SHM.")
1264 (intoname)
1265 Lisp_Object intoname;
1266 {
1267 extern char my_edata[];
1268 Lisp_Object tem;
1269
1270 CHECK_STRING (intoname, 0);
1271 intoname = Fexpand_file_name (intoname, Qnil);
1272
1273 tem = Vpurify_flag;
1274 Vpurify_flag = Qnil;
1275
1276 fflush (stdout);
1277 /* Tell malloc where start of impure now is */
1278 /* Also arrange for warnings when nearly out of space. */
1279 #ifndef SYSTEM_MALLOC
1280 memory_warnings (my_edata, malloc_warning);
1281 #endif
1282 map_out_data (XSTRING (intoname)->data);
1283
1284 Vpurify_flag = tem;
1285
1286 return Qnil;
1287 }
1288
1289 #else /* not HAVE_SHM */
1290
1291 DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0,
1292 "Dump current state of Emacs into executable file FILENAME.\n\
1293 Take symbols from SYMFILE (presumably the file you executed to run Emacs).\n\
1294 This is used in the file `loadup.el' when building Emacs.\n\
1295 \n\
1296 Bind `command-line-processed' to nil before dumping,\n\
1297 if you want the dumped Emacs to process its command line\n\
1298 and announce itself normally when it is run.")
1299 (intoname, symname)
1300 Lisp_Object intoname, symname;
1301 {
1302 extern char my_edata[];
1303 Lisp_Object tem;
1304
1305 CHECK_STRING (intoname, 0);
1306 intoname = Fexpand_file_name (intoname, Qnil);
1307 if (!NILP (symname))
1308 {
1309 CHECK_STRING (symname, 0);
1310 if (XSTRING (symname)->size)
1311 symname = Fexpand_file_name (symname, Qnil);
1312 }
1313
1314 tem = Vpurify_flag;
1315 Vpurify_flag = Qnil;
1316
1317 fflush (stdout);
1318 #ifdef VMS
1319 mapout_data (XSTRING (intoname)->data);
1320 #else
1321 /* Tell malloc where start of impure now is */
1322 /* Also arrange for warnings when nearly out of space. */
1323 #ifndef SYSTEM_MALLOC
1324 #ifndef WINDOWSNT
1325 /* On Windows, this was done before dumping, and that once suffices.
1326 Meanwhile, my_edata is not valid on Windows. */
1327 memory_warnings (my_edata, malloc_warning);
1328 #endif /* not WINDOWSNT */
1329 #endif
1330 unexec (XSTRING (intoname)->data,
1331 !NILP (symname) ? XSTRING (symname)->data : 0, my_edata, 0, 0);
1332 #endif /* not VMS */
1333
1334 Vpurify_flag = tem;
1335
1336 return Qnil;
1337 }
1338
1339 #endif /* not HAVE_SHM */
1340
1341 #endif /* not CANNOT_DUMP */
1342 \f
1343 #ifndef SEPCHAR
1344 #define SEPCHAR ':'
1345 #endif
1346
1347 Lisp_Object
1348 decode_env_path (evarname, defalt)
1349 char *evarname, *defalt;
1350 {
1351 register char *path, *p;
1352
1353 Lisp_Object lpath;
1354
1355 /* It's okay to use getenv here, because this function is only used
1356 to initialize variables when Emacs starts up, and isn't called
1357 after that. */
1358 if (evarname != 0)
1359 path = (char *) getenv (evarname);
1360 else
1361 path = 0;
1362 if (!path)
1363 path = defalt;
1364 lpath = Qnil;
1365 while (1)
1366 {
1367 p = index (path, SEPCHAR);
1368 if (!p) p = path + strlen (path);
1369 lpath = Fcons (p - path ? make_string (path, p - path)
1370 : build_string ("."),
1371 lpath);
1372 if (*p)
1373 path = p + 1;
1374 else
1375 break;
1376 }
1377 return Fnreverse (lpath);
1378 }
1379
1380 syms_of_emacs ()
1381 {
1382 #ifndef CANNOT_DUMP
1383 #ifdef HAVE_SHM
1384 defsubr (&Sdump_emacs_data);
1385 #else
1386 defsubr (&Sdump_emacs);
1387 #endif
1388 #endif
1389
1390 defsubr (&Skill_emacs);
1391
1392 defsubr (&Sinvocation_name);
1393 defsubr (&Sinvocation_directory);
1394
1395 DEFVAR_LISP ("command-line-args", &Vcommand_line_args,
1396 "Args passed by shell to Emacs, as a list of strings.");
1397
1398 DEFVAR_LISP ("system-type", &Vsystem_type,
1399 "Value is symbol indicating type of operating system you are using.");
1400 Vsystem_type = intern (SYSTEM_TYPE);
1401
1402 DEFVAR_LISP ("system-configuration", &Vsystem_configuration,
1403 "Value is string indicating configuration Emacs was built for.");
1404 Vsystem_configuration = build_string (EMACS_CONFIGURATION);
1405
1406 DEFVAR_LISP ("system-configuration-options", &Vsystem_configuration_options,
1407 "String containing the configuration options Emacs was built with.");
1408 Vsystem_configuration_options = build_string (EMACS_CONFIG_OPTIONS);
1409
1410 DEFVAR_BOOL ("noninteractive", &noninteractive1,
1411 "Non-nil means Emacs is running without interactive terminal.");
1412
1413 DEFVAR_LISP ("kill-emacs-hook", &Vkill_emacs_hook,
1414 "Hook to be run whenever kill-emacs is called.\n\
1415 Since kill-emacs may be invoked when the terminal is disconnected (or\n\
1416 in other similar situations), functions placed on this hook should not\n\
1417 expect to be able to interact with the user. To ask for confirmation,\n\
1418 see `kill-emacs-query-functions' instead.");
1419 Vkill_emacs_hook = Qnil;
1420
1421 DEFVAR_INT ("emacs-priority", &emacs_priority,
1422 "Priority for Emacs to run at.\n\
1423 This value is effective only if set before Emacs is dumped,\n\
1424 and only if the Emacs executable is installed with setuid to permit\n\
1425 it to change priority. (Emacs sets its uid back to the real uid.)\n\
1426 Currently, you need to define SET_EMACS_PRIORITY in `config.h'\n\
1427 before you compile Emacs, to enable the code for this feature.");
1428 emacs_priority = 0;
1429
1430 DEFVAR_LISP ("invocation-name", &Vinvocation_name,
1431 "The program name that was used to run Emacs.\n\
1432 Any directory names are omitted.");
1433
1434 DEFVAR_LISP ("invocation-directory", &Vinvocation_directory,
1435 "The directory in which the Emacs executable was found, to run it.\n\
1436 The value is nil if that directory's name is not known.");
1437
1438 DEFVAR_LISP ("installation-directory", &Vinstallation_directory,
1439 "A directory within which to look for the `lib-src' and `etc' directories.\n\
1440 This is non-nil when we can't find those directories in their standard\n\
1441 installed locations, but we can find them\n\
1442 near where the Emacs executable was found.");
1443 Vinstallation_directory = Qnil;
1444 }