*** empty log message ***
[emacs.git] / src / emacs.c
blobc530eca103ff6611c51c42fd0029211eed03dc96
1 /* Fully extensible Emacs, running on Unix, intended for GNU.
2 Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
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 1, or (at your option)
9 any later version.
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.
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. */
21 #include <signal.h>
22 #include <errno.h>
24 #include "config.h"
25 #include <stdio.h>
27 #include <sys/types.h>
28 #include <sys/file.h>
30 #ifdef VMS
31 #include <ssdef.h>
32 #endif
34 #ifdef USG5
35 #include <fcntl.h>
36 #endif
38 #ifdef BSD
39 #include <sys/ioctl.h>
40 #endif
42 #ifdef HAVE_TERMIOS
43 #include <termios.h>
44 #endif
46 #ifdef APOLLO
47 #ifndef APOLLO_SR10
48 #include <default_acl.h>
49 #endif
50 #endif
52 #include "lisp.h"
53 #include "commands.h"
55 #include "systerm.h"
57 #ifndef O_RDWR
58 #define O_RDWR 2
59 #endif
61 #define PRIO_PROCESS 0
63 /* Command line args from shell, as list of strings */
64 Lisp_Object Vcommand_line_args;
66 /* Set nonzero after Emacs has started up the first time.
67 Prevents reinitialization of the Lisp world and keymaps
68 on subsequent starts. */
69 int initialized;
71 /* Variable whose value is symbol giving operating system type */
72 Lisp_Object Vsystem_type;
74 /* If non-zero, emacs should not attempt to use an window-specific code,
75 but instead should use the virtual terminal under which it was started */
76 int inhibit_window_system;
78 #ifdef HAVE_X_WINDOWS
79 /* If non-zero, -d was specified, meaning we're using some window system. */
80 int display_arg;
81 #endif
83 /* An address near the bottom of the stack.
84 Tells GC how to save a copy of the stack. */
85 char *stack_bottom;
87 #ifdef HAVE_X_WINDOWS
88 extern Lisp_Object Vwindow_system;
89 #endif /* HAVE_X_WINDOWS */
91 #ifdef USG_SHARED_LIBRARIES
92 /* If nonzero, this is the place to put the end of the writable segment
93 at startup. */
95 unsigned int bss_end = 0;
96 #endif
98 /* Nonzero means running Emacs without interactive terminal. */
100 int noninteractive;
102 /* Value of Lisp variable `noninteractive'.
103 Normally same as C variable `noninteractive'
104 but nothing terrible happens if user sets this one. */
106 int noninteractive1;
108 /* Signal code for the fatal signal that was received */
109 int fatal_error_code;
111 /* Nonzero if handling a fatal error already */
112 int fatal_error_in_progress;
114 /* Handle bus errors, illegal instruction, etc. */
115 SIGTYPE
116 fatal_error_signal (sig)
117 int sig;
119 fatal_error_code = sig;
120 signal (sig, SIG_DFL);
122 /* If fatal error occurs in code below, avoid infinite recursion. */
123 if (fatal_error_in_progress)
124 kill (getpid (), fatal_error_code);
126 fatal_error_in_progress = 1;
128 /* If we are controlling the terminal, reset terminal modes */
129 #ifdef EMACS_HAVE_TTY_PGRP
131 int tpgrp;
132 if (EMACS_GET_TTY_PGRP (0, &tpgrp) != -1
133 && tpgrp == getpgrp (0))
135 reset_sys_modes ();
136 if (sig != SIGTERM)
137 fprintf (stderr, "Fatal error (%d).", sig);
140 #endif /* uses pgrp */
142 /* Clean up */
143 kill_buffer_processes (Qnil);
144 Fdo_auto_save (Qt, Qnil);
146 #ifdef CLASH_DETECTION
147 unlock_all_files ();
148 #endif /* CLASH_DETECTION */
150 #ifdef VMS
151 kill_vms_processes ();
152 LIB$STOP (SS$_ABORT);
153 #else
154 /* Signal the same code; this time it will really be fatal. */
155 kill (getpid (), fatal_error_code);
156 #endif /* not VMS */
159 /* Code for dealing with Lisp access to the Unix command line */
161 static
162 init_cmdargs (argc, argv, skip_args)
163 int argc;
164 char **argv;
165 int skip_args;
167 register int i;
169 Vcommand_line_args = Qnil;
171 for (i = argc - 1; i >= 0; i--)
173 if (i == 0 || i > skip_args)
174 Vcommand_line_args
175 = Fcons (build_string (argv[i]), Vcommand_line_args);
179 #ifdef VMS
180 #ifdef LINK_CRTL_SHARE
181 #ifdef SHAREABLE_LIB_BUG
182 extern noshare char **environ;
183 #endif /* SHAREABLE_LIB_BUG */
184 #endif /* LINK_CRTL_SHARE */
185 #endif /* VMS */
187 /* ARGSUSED */
188 main (argc, argv, envp)
189 int argc;
190 char **argv;
191 char **envp;
193 char stack_bottom_variable;
194 int skip_args = 0;
195 extern int errno;
196 extern sys_nerr;
197 extern char *sys_errlist[];
198 extern void malloc_warning ();
200 /* Map in shared memory, if we are using that. */
201 #ifdef HAVE_SHM
202 if (argc > 1 && !strcmp (argv[1], "-nl"))
204 map_in_data (0);
205 /* The shared memory was just restored, which clobbered this. */
206 skip_args = 1;
208 else
210 map_in_data (1);
211 /* The shared memory was just restored, which clobbered this. */
212 skip_args = 0;
214 #endif
216 #ifdef HAVE_X_WINDOWS
217 /* Stupid kludge to catch command-line display spec. We can't
218 handle this argument entirely in window system dependent code
219 because we don't even know which window system dependent code
220 to run until we've recognized this argument. */
222 int i;
224 for (i = 1; (i < argc && ! display_arg); i++)
225 if (!strcmp (argv[i], "-d"))
226 display_arg = 1;
228 #endif
230 #ifdef VMS
231 /* If -map specified, map the data file in */
232 if (argc > 2 && ! strcmp (argv[1], "-map"))
234 skip_args = 2;
235 mapin_data (argv[2]);
238 #ifdef LINK_CRTL_SHARE
239 #ifdef SHAREABLE_LIB_BUG
240 /* Bletcherous shared libraries! */
241 if (!stdin)
242 stdin = fdopen (0, "r");
243 if (!stdout)
244 stdout = fdopen (1, "w");
245 if (!stderr)
246 stderr = fdopen (2, "w");
247 if (!environ)
248 environ = envp;
249 #endif /* SHAREABLE_LIB_BUG */
250 #endif /* LINK_CRTL_SHARE */
251 #endif /* VMS */
253 /* Record (approximately) where the stack begins. */
254 stack_bottom = &stack_bottom_variable;
256 #ifdef RUN_TIME_REMAP
257 if (initialized)
258 run_time_remap (argv[0]);
259 #endif
261 #ifdef USG_SHARED_LIBRARIES
262 if (bss_end)
263 brk (bss_end);
264 #endif
266 clearerr (stdin);
267 #ifdef BSD
268 setpgrp (0, getpid ());
269 #endif
271 #ifdef APOLLO
272 #ifndef APOLLO_SR10
273 /* If USE_DOMAIN_ACLS environment variable exists,
274 use ACLs rather than UNIX modes. */
275 if (egetenv ("USE_DOMAIN_ACLS"))
276 default_acl (USE_DEFACL);
277 #endif
278 #endif /* APOLLO */
280 #ifndef SYSTEM_MALLOC
281 if (! initialized)
282 malloc_init (0, malloc_warning);
283 #endif /* not SYSTEM_MALLOC */
285 #ifdef HIGHPRI
286 setpriority (PRIO_PROCESS, getpid (), HIGHPRI);
287 setuid (getuid ());
288 #endif /* HIGHPRI */
290 #ifdef BSD
291 /* interrupt_input has trouble if we aren't in a separate process group. */
292 setpgrp (getpid (), getpid ());
293 #endif
295 inhibit_window_system = 0;
297 /* Handle the -t switch, which specifies filename to use as terminal */
298 if (skip_args + 2 < argc && !strcmp (argv[skip_args + 1], "-t"))
300 int result;
301 skip_args += 2;
302 close (0);
303 close (1);
304 result = open (argv[skip_args], O_RDWR, 2 );
305 if (result < 0)
307 char *errstring;
309 if (errno >= 0 && errno < sys_nerr)
310 errstring = sys_errlist[errno];
311 else
312 errstring = "undocumented error code";
313 fprintf (stderr, "emacs: %s: %s\n", argv[skip_args], errstring);
314 exit (1);
316 dup (0);
317 if (! isatty (0))
319 fprintf (stderr, "emacs: %s: not a tty\n", argv[skip_args]);
320 exit (1);
322 fprintf (stderr, "Using %s\n", argv[skip_args]);
323 #ifdef HAVE_X_WINDOWS
324 inhibit_window_system = 1; /* -t => -nw */
325 #endif
328 if (skip_args + 1 < argc
329 && (!strcmp (argv[skip_args + 1], "-nw")))
331 skip_args += 1;
332 inhibit_window_system = 1;
335 /* Handle the -batch switch, which means don't do interactive display. */
336 noninteractive = 0;
337 if (skip_args + 1 < argc && !strcmp (argv[skip_args + 1], "-batch"))
339 skip_args += 1;
340 noninteractive = 1;
343 #ifdef POSIX_SIGNALS
344 init_signals ();
345 #endif
347 if (
348 #ifndef CANNOT_DUMP
349 ! noninteractive || initialized
350 #else
352 #endif
355 /* Don't catch these signals in batch mode if not initialized.
356 On some machines, this sets static data that would make
357 signal fail to work right when the dumped Emacs is run. */
358 signal (SIGHUP, fatal_error_signal);
359 signal (SIGQUIT, fatal_error_signal);
360 signal (SIGILL, fatal_error_signal);
361 signal (SIGTRAP, fatal_error_signal);
362 signal (SIGIOT, fatal_error_signal);
363 #ifdef SIGEMT
364 signal (SIGEMT, fatal_error_signal);
365 #endif
366 signal (SIGFPE, fatal_error_signal);
367 signal (SIGBUS, fatal_error_signal);
368 signal (SIGSEGV, fatal_error_signal);
369 signal (SIGSYS, fatal_error_signal);
370 signal (SIGTERM, fatal_error_signal);
371 #ifdef SIGXCPU
372 signal (SIGXCPU, fatal_error_signal);
373 #endif
374 #ifdef SIGXFSZ
375 signal (SIGXFSZ, fatal_error_signal);
376 #endif /* SIGXFSZ */
378 #ifdef AIX
379 signal (SIGDANGER, fatal_error_signal);
380 signal (20, fatal_error_signal);
381 signal (21, fatal_error_signal);
382 signal (22, fatal_error_signal);
383 signal (23, fatal_error_signal);
384 signal (24, fatal_error_signal);
385 #ifdef SIGIO
386 signal (SIGAIO, fatal_error_signal);
387 signal (SIGPTY, fatal_error_signal);
388 #endif
389 signal (SIGIOINT, fatal_error_signal);
390 signal (SIGGRANT, fatal_error_signal);
391 signal (SIGRETRACT, fatal_error_signal);
392 signal (SIGSOUND, fatal_error_signal);
393 signal (SIGMSG, fatal_error_signal);
394 #endif /* AIX */
397 noninteractive1 = noninteractive;
399 /* Perform basic initializations (not merely interning symbols) */
401 if (!initialized)
403 init_alloc_once ();
404 init_obarray ();
405 init_eval_once ();
406 init_syntax_once (); /* Create standard syntax table. */
407 /* Must be done before init_buffer */
408 init_casetab_once ();
409 init_buffer_once (); /* Create buffer table and some buffers */
410 init_minibuf_once (); /* Create list of minibuffers */
411 /* Must precede init_window_once */
412 init_window_once (); /* Init the window system */
415 init_alloc ();
416 init_eval ();
417 init_data ();
418 init_lread ();
420 init_cmdargs (argc, argv, skip_args); /* Create list Vcommand_line_args */
421 init_buffer (); /* Init default directory of main buffer */
422 if (!noninteractive)
424 #ifdef VMS
425 init_vms_input ();/* init_display calls get_screen_size, that needs this */
426 #endif /* VMS */
427 init_display (); /* Determine terminal type. init_sys_modes uses results */
429 init_keyboard (); /* This too must precede init_sys_modes */
430 init_callproc (); /* And this too. */
431 #ifdef VMS
432 init_vmsproc (); /* And this too. */
433 #endif /* VMS */
434 init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.) */
435 init_xdisp ();
436 init_macros ();
437 init_editfns ();
438 #ifdef LISP_FLOAT_TYPE
439 init_floatfns ();
440 #endif
441 #ifdef VMS
442 init_vmsfns ();
443 #endif /* VMS */
444 init_process ();
446 /* Intern the names of all standard functions and variables; define standard keys */
448 if (!initialized)
450 /* The basic levels of Lisp must come first */
451 /* And data must come first of all
452 for the sake of symbols like error-message */
453 syms_of_data ();
454 syms_of_alloc ();
455 syms_of_lread ();
456 syms_of_print ();
457 syms_of_eval ();
458 syms_of_fns ();
459 #ifdef LISP_FLOAT_TYPE
460 syms_of_floatfns ();
461 #endif
463 syms_of_abbrev ();
464 syms_of_buffer ();
465 syms_of_bytecode ();
466 syms_of_callint ();
467 syms_of_casefiddle ();
468 syms_of_casetab ();
469 syms_of_callproc ();
470 syms_of_cmds ();
471 #ifndef NO_DIR_LIBRARY
472 syms_of_dired ();
473 #endif /* not NO_DIR_LIBRARY */
474 syms_of_display ();
475 syms_of_doc ();
476 syms_of_editfns ();
477 syms_of_emacs ();
478 syms_of_fileio ();
479 #ifdef CLASH_DETECTION
480 syms_of_filelock ();
481 #endif /* CLASH_DETECTION */
482 syms_of_indent ();
483 syms_of_keyboard ();
484 syms_of_keymap ();
485 syms_of_macros ();
486 syms_of_marker ();
487 syms_of_minibuf ();
488 syms_of_mocklisp ();
489 syms_of_process ();
490 syms_of_search ();
491 #ifdef MULTI_SCREEN
492 syms_of_screen ();
493 #endif
494 syms_of_syntax ();
495 syms_of_undo ();
496 #ifdef VMS
497 syms_of_vmsproc ();
498 #endif /* VMS */
499 syms_of_window ();
500 syms_of_xdisp ();
501 #ifdef HAVE_X_WINDOWS
502 syms_of_xterm ();
503 syms_of_xfns ();
504 #ifdef HAVE_X11
505 syms_of_xselect ();
506 #endif
507 #ifdef HAVE_X_MENU
508 syms_of_xmenu ();
509 #endif /* HAVE_X_MENU */
510 #endif /* HAVE_X_WINDOWS */
512 #ifdef SYMS_SYSTEM
513 SYMS_SYSTEM;
514 #endif
516 #ifdef SYMS_MACHINE
517 SYMS_MACHINE;
518 #endif
520 keys_of_casefiddle ();
521 keys_of_cmds ();
522 keys_of_buffer ();
523 keys_of_keyboard ();
524 keys_of_keymap ();
525 keys_of_macros ();
526 keys_of_minibuf ();
527 keys_of_window ();
530 if (!initialized)
532 /* Handle -l loadup-and-dump, args passed by Makefile. */
533 if (argc > 2 + skip_args && !strcmp (argv[1 + skip_args], "-l"))
534 Vtop_level = Fcons (intern ("load"),
535 Fcons (build_string (argv[2 + skip_args]), Qnil));
536 #ifdef CANNOT_DUMP
537 /* Unless next switch is -nl, load "loadup.el" first thing. */
538 if (!(argc > 1 + skip_args && !strcmp (argv[1 + skip_args], "-nl")))
539 Vtop_level = Fcons (intern ("load"),
540 Fcons (build_string ("loadup.el"), Qnil));
541 #endif /* CANNOT_DUMP */
544 initialized = 1;
546 /* Enter editor command loop. This never returns. */
547 Frecursive_edit ();
548 /* NOTREACHED */
551 DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P",
552 "Exit the Emacs job and kill it. Ask for confirmation, without argument.\n\
553 If ARG is an integer, return ARG as the exit program code.\n\
554 If ARG is a string, stuff it as keyboard input.\n\n\
555 The value of `kill-emacs-hook', if not void,\n\
556 is a list of functions (of no args),\n\
557 all of which are called before Emacs is actually killed.")
558 (arg)
559 Lisp_Object arg;
561 Lisp_Object hook, hook1;
562 int i;
563 struct gcpro gcpro1;
565 GCPRO1 (arg);
567 if (feof (stdin))
568 arg = Qt;
570 if (!NILP (Vrun_hooks) && !noninteractive)
571 call1 (Vrun_hooks, intern ("kill-emacs-hook"));
573 kill_buffer_processes (Qnil);
575 #ifdef VMS
576 kill_vms_processes ();
577 #endif /* VMS */
579 Fdo_auto_save (Qt, Qnil);
581 #ifdef CLASH_DETECTION
582 unlock_all_files ();
583 #endif /* CLASH_DETECTION */
585 fflush (stdout);
586 reset_sys_modes ();
588 #ifdef HAVE_X_WINDOWS
589 if (!noninteractive && EQ (Vwindow_system, intern ("x")))
590 Fx_close_current_connection ();
591 #endif /* HAVE_X_WINDOWS */
593 UNGCPRO;
595 /* Is it really necessary to do this deassign
596 when we are going to exit anyway? */
597 /* #ifdef VMS
598 stop_vms_input ();
599 #endif */
600 stuff_buffered_input (arg);
601 #ifdef SIGIO
602 /* There is a tendency for a SIGIO signal to arrive within exit,
603 and cause a SIGHUP because the input descriptor is already closed. */
604 unrequest_sigio ();
605 signal (SIGIO, SIG_IGN);
606 #endif
607 exit ((XTYPE (arg) == Lisp_Int) ? XINT (arg)
608 #ifdef VMS
610 #else
612 #endif
614 /* NOTREACHED */
617 #ifndef CANNOT_DUMP
618 /* Nothing like this can be implemented on an Apollo.
619 What a loss! */
621 #ifdef HAVE_SHM
623 DEFUN ("dump-emacs-data", Fdump_emacs_data, Sdump_emacs_data, 1, 1, 0,
624 "Dump current state of Emacs into data file FILENAME.\n\
625 This function exists on systems that use HAVE_SHM.")
626 (intoname)
627 Lisp_Object intoname;
629 extern int my_edata;
630 Lisp_Object tem;
631 extern void malloc_warning ();
633 CHECK_STRING (intoname, 0);
634 intoname = Fexpand_file_name (intoname, Qnil);
636 tem = Vpurify_flag;
637 Vpurify_flag = Qnil;
639 fflush (stdout);
640 /* Tell malloc where start of impure now is */
641 /* Also arrange for warnings when nearly out of space. */
642 #ifndef SYSTEM_MALLOC
643 malloc_init (&my_edata, malloc_warning);
644 #endif
645 map_out_data (XSTRING (intoname)->data);
647 Vpurify_flag = tem;
649 return Qnil;
652 #else /* not HAVE_SHM */
654 DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0,
655 "Dump current state of Emacs into executable file FILENAME.\n\
656 Take symbols from SYMFILE (presumably the file you executed to run Emacs).\n\
657 This is used in the file `loadup.el' when building Emacs.\n\
659 Bind `command-line-processed' to nil before dumping,\n\
660 if you want the dumped Emacs to process its command line\n\
661 and announce itself normally when it is run.")
662 (intoname, symname)
663 Lisp_Object intoname, symname;
665 extern int my_edata;
666 Lisp_Object tem;
667 extern void malloc_warning ();
669 CHECK_STRING (intoname, 0);
670 intoname = Fexpand_file_name (intoname, Qnil);
671 if (!NILP (symname))
673 CHECK_STRING (symname, 0);
674 if (XSTRING (symname)->size)
675 symname = Fexpand_file_name (symname, Qnil);
678 tem = Vpurify_flag;
679 Vpurify_flag = Qnil;
681 fflush (stdout);
682 #ifdef VMS
683 mapout_data (XSTRING (intoname)->data);
684 #else
685 /* Tell malloc where start of impure now is */
686 /* Also arrange for warnings when nearly out of space. */
687 #ifndef SYSTEM_MALLOC
688 malloc_init (&my_edata, malloc_warning);
689 #endif
690 unexec (XSTRING (intoname)->data,
691 !NILP (symname) ? XSTRING (symname)->data : 0, &my_edata, 0, 0);
692 #endif /* not VMS */
694 Vpurify_flag = tem;
696 return Qnil;
699 #endif /* not HAVE_SHM */
701 #endif /* not CANNOT_DUMP */
703 #ifdef VMS
704 #define SEPCHAR ','
705 #else
706 #define SEPCHAR ':'
707 #endif
709 Lisp_Object
710 decode_env_path (evarname, defalt)
711 char *evarname, *defalt;
713 register char *path, *p;
714 extern char *index ();
716 Lisp_Object lpath;
718 /* It's okay to use getenv here, because this function is only used
719 to initialize variables when Emacs starts up, and isn't called
720 after that. */
721 path = (char *) getenv (evarname);
722 if (!path)
723 path = defalt;
724 lpath = Qnil;
725 while (1)
727 p = index (path, SEPCHAR);
728 if (!p) p = path + strlen (path);
729 lpath = Fcons (p - path ? make_string (path, p - path) : Qnil,
730 lpath);
731 if (*p)
732 path = p + 1;
733 else
734 break;
736 return Fnreverse (lpath);
739 syms_of_emacs ()
741 #ifdef HAVE_SHM
742 defsubr (&Sdump_emacs_data);
743 #else
744 defsubr (&Sdump_emacs);
745 #endif
747 defsubr (&Skill_emacs);
749 DEFVAR_LISP ("command-line-args", &Vcommand_line_args,
750 "Args passed by shell to Emacs, as a list of strings.");
752 DEFVAR_LISP ("system-type", &Vsystem_type,
753 "Value is symbol indicating type of operating system you are using.");
754 Vsystem_type = intern (SYSTEM_TYPE);
756 DEFVAR_BOOL ("noninteractive", &noninteractive1,
757 "Non-nil means Emacs is running without interactive terminal.");