1 /* Fully extensible Emacs, running on Unix, intended for GNU.
2 Copyright (C) 1985, 1986, 1987 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)
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. */
27 #include <sys/types.h>
39 #include <sys/ioctl.h>
44 #include <default_acl.h>
56 #define PRIO_PROCESS 0
58 /* Command line args from shell, as list of strings */
59 Lisp_Object Vcommand_line_args
;
61 /* Set nonzero after Emacs has started up the first time.
62 Prevents reinitialization of the Lisp world and keymaps
63 on subsequent starts. */
66 /* Variable whose value is symbol giving operating system type */
67 Lisp_Object Vsystem_type
;
69 /* If non-zero, emacs should not attempt to use an window-specific code,
70 but instead should use the virtual terminal under which it was started */
71 int inhibit_window_system
;
74 /* If non-zero, -d was specified, meaning we're using some window system. */
78 /* An address near the bottom of the stack.
79 Tells GC how to save a copy of the stack. */
83 extern Lisp_Object Vwindow_system
;
84 #endif /* HAVE_X_WINDOWS */
86 #ifdef USG_SHARED_LIBRARIES
87 /* If nonzero, this is the place to put the end of the writable segment
90 unsigned int bss_end
= 0;
93 /* Nonzero means running Emacs without interactive terminal. */
97 /* Value of Lisp variable `noninteractive'.
98 Normally same as C variable `noninteractive'
99 but nothing terrible happens if user sets this one. */
103 /* Signal code for the fatal signal that was received */
104 int fatal_error_code
;
106 /* Nonzero if handling a fatal error already */
107 int fatal_error_in_progress
;
109 /* Handle bus errors, illegal instruction, etc. */
110 fatal_error_signal (sig
)
117 fatal_error_code
= sig
;
118 signal (sig
, SIG_DFL
);
120 /* If fatal error occurs in code below, avoid infinite recursion. */
121 if (fatal_error_in_progress
)
122 kill (getpid (), fatal_error_code
);
124 fatal_error_in_progress
= 1;
126 /* If we are controlling the terminal, reset terminal modes */
128 if (ioctl(0, TIOCGPGRP
, &tpgrp
) == 0
129 && tpgrp
== getpgrp (0))
134 fprintf (stderr
, "Fatal error (%d).", sig
);
139 kill_buffer_processes (Qnil
);
141 Fdo_auto_save (Qt
, Qnil
);
143 #ifdef CLASH_DETECTION
145 #endif /* CLASH_DETECTION */
148 kill_vms_processes ();
149 LIB$
STOP (SS$_ABORT
);
151 /* Signal the same code; this time it will really be fatal. */
152 kill (getpid (), fatal_error_code
);
156 /* Code for dealing with Lisp access to the Unix command line */
159 init_cmdargs (argc
, argv
, skip_args
)
166 Vcommand_line_args
= Qnil
;
168 for (i
= argc
- 1; i
>= 0; i
--)
170 if (i
== 0 || i
> skip_args
)
172 = Fcons (build_string (argv
[i
]), Vcommand_line_args
);
177 #ifdef LINK_CRTL_SHARE
178 #ifdef SHAREABLE_LIB_BUG
179 extern noshare
char **environ
;
180 #endif /* SHAREABLE_LIB_BUG */
181 #endif /* LINK_CRTL_SHARE */
185 main (argc
, argv
, envp
)
190 char stack_bottom_variable
;
194 extern char *sys_errlist
[];
195 extern void malloc_warning ();
197 /* Map in shared memory, if we are using that. */
199 if (argc
> 1 && !strcmp (argv
[1], "-nl"))
202 /* The shared memory was just restored, which clobbered this. */
208 /* The shared memory was just restored, which clobbered this. */
213 #ifdef HAVE_X_WINDOWS
214 /* Stupid kludge to catch command-line display spec. We can't
215 handle this argument entirely in window system dependent code
216 because we don't even know which window system dependent code
217 to run until we've recognized this argument. */
221 for (i
= 1; (i
< argc
&& ! display_arg
); i
++)
222 if (!strcmp (argv
[i
], "-d"))
228 /* If -map specified, map the data file in */
229 if (argc
> 2 && ! strcmp (argv
[1], "-map"))
232 mapin_data (argv
[2]);
235 #ifdef LINK_CRTL_SHARE
236 #ifdef SHAREABLE_LIB_BUG
237 /* Bletcherous shared libraries! */
239 stdin
= fdopen (0, "r");
241 stdout
= fdopen (1, "w");
243 stderr
= fdopen (2, "w");
246 #endif /* SHAREABLE_LIB_BUG */
247 #endif /* LINK_CRTL_SHARE */
250 /* Record (approximately) where the stack begins. */
251 stack_bottom
= &stack_bottom_variable
;
253 #ifdef RUN_TIME_REMAP
255 run_time_remap (argv
[0]);
258 #ifdef USG_SHARED_LIBRARIES
265 setpgrp (0, getpid ());
270 /* If USE_DOMAIN_ACLS environment variable exists,
271 use ACLs rather than UNIX modes. */
272 if (egetenv ("USE_DOMAIN_ACLS"))
273 default_acl (USE_DEFACL
);
277 #ifndef SYSTEM_MALLOC
279 malloc_init (0, malloc_warning
);
280 #endif /* not SYSTEM_MALLOC */
283 setpriority (PRIO_PROCESS
, getpid (), HIGHPRI
);
288 /* interrupt_input has trouble if we aren't in a separate process group. */
289 setpgrp (getpid (), getpid ());
292 inhibit_window_system
= 0;
294 /* Handle the -t switch, which specifies filename to use as terminal */
295 if (skip_args
+ 2 < argc
&& !strcmp (argv
[skip_args
+ 1], "-t"))
301 result
= open (argv
[skip_args
], O_RDWR
, 2 );
306 if (errno
>= 0 && errno
< sys_nerr
)
307 errstring
= sys_errlist
[errno
];
309 errstring
= "undocumented error code";
310 fprintf (stderr
, "emacs: %s: %s\n", argv
[skip_args
], errstring
);
316 fprintf (stderr
, "emacs: %s: not a tty\n", argv
[skip_args
]);
319 fprintf (stderr
, "Using %s\n", argv
[skip_args
]);
320 #ifdef HAVE_X_WINDOWS
321 inhibit_window_system
= 1; /* -t => -nw */
325 if (skip_args
+ 1 < argc
326 && (!strcmp (argv
[skip_args
+ 1], "-nw")))
329 inhibit_window_system
= 1;
332 /* Handle the -batch switch, which means don't do interactive display. */
334 if (skip_args
+ 1 < argc
&& !strcmp (argv
[skip_args
+ 1], "-batch"))
346 ! noninteractive
|| initialized
352 /* Don't catch these signals in batch mode if not initialized.
353 On some machines, this sets static data that would make
354 signal fail to work right when the dumped Emacs is run. */
355 signal (SIGHUP
, fatal_error_signal
);
356 signal (SIGQUIT
, fatal_error_signal
);
357 signal (SIGILL
, fatal_error_signal
);
358 signal (SIGTRAP
, fatal_error_signal
);
359 signal (SIGIOT
, fatal_error_signal
);
361 signal (SIGEMT
, fatal_error_signal
);
363 signal (SIGFPE
, fatal_error_signal
);
364 signal (SIGBUS
, fatal_error_signal
);
365 signal (SIGSEGV
, fatal_error_signal
);
366 signal (SIGSYS
, fatal_error_signal
);
367 signal (SIGTERM
, fatal_error_signal
);
369 signal (SIGXCPU
, fatal_error_signal
);
372 signal (SIGXFSZ
, fatal_error_signal
);
376 signal (SIGDANGER
, fatal_error_signal
);
377 signal (20, fatal_error_signal
);
378 signal (21, fatal_error_signal
);
379 signal (22, fatal_error_signal
);
380 signal (23, fatal_error_signal
);
381 signal (24, fatal_error_signal
);
383 signal (SIGAIO
, fatal_error_signal
);
384 signal (SIGPTY
, fatal_error_signal
);
386 signal (SIGIOINT
, fatal_error_signal
);
387 signal (SIGGRANT
, fatal_error_signal
);
388 signal (SIGRETRACT
, fatal_error_signal
);
389 signal (SIGSOUND
, fatal_error_signal
);
390 signal (SIGMSG
, fatal_error_signal
);
394 noninteractive1
= noninteractive
;
396 /* Perform basic initializations (not merely interning symbols) */
403 init_syntax_once (); /* Create standard syntax table. */
404 /* Must be done before init_buffer */
405 init_casetab_once ();
406 init_buffer_once (); /* Create buffer table and some buffers */
407 init_minibuf_once (); /* Create list of minibuffers */
408 /* Must precede init_window_once */
409 init_window_once (); /* Init the window system */
413 #ifdef MAINTAIN_ENVIRONMENT
420 init_cmdargs (argc
, argv
, skip_args
); /* Create list Vcommand_line_args */
421 init_buffer (); /* Init default directory of main buffer */
425 init_vms_input ();/* init_display calls get_screen_size, that needs this */
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. */
432 init_vmsproc (); /* And this too. */
434 init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.) */
438 #ifdef LISP_FLOAT_TYPE
446 #endif /* subprocesses */
448 /* Intern the names of all standard functions and variables; define standard keys */
452 /* The basic levels of Lisp must come first */
453 /* And data must come first of all
454 for the sake of symbols like error-message */
457 #ifdef MAINTAIN_ENVIRONMENT
459 #endif /* MAINTAIN_ENVIRONMENT */
464 #ifdef LISP_FLOAT_TYPE
472 syms_of_casefiddle ();
476 #ifndef NO_DIR_LIBRARY
478 #endif /* not NO_DIR_LIBRARY */
484 #ifdef CLASH_DETECTION
486 #endif /* CLASH_DETECTION */
496 #endif /* subprocesses */
508 #ifdef HAVE_X_WINDOWS
516 #endif /* HAVE_X_MENU */
517 #endif /* HAVE_X_WINDOWS */
527 keys_of_casefiddle ();
539 /* Handle -l loadup-and-dump, args passed by Makefile. */
540 if (argc
> 2 + skip_args
&& !strcmp (argv
[1 + skip_args
], "-l"))
541 Vtop_level
= Fcons (intern ("load"),
542 Fcons (build_string (argv
[2 + skip_args
]), Qnil
));
544 /* Unless next switch is -nl, load "loadup.el" first thing. */
545 if (!(argc
> 1 + skip_args
&& !strcmp (argv
[1 + skip_args
], "-nl")))
546 Vtop_level
= Fcons (intern ("load"),
547 Fcons (build_string ("loadup.el"), Qnil
));
548 #endif /* CANNOT_DUMP */
553 /* Enter editor command loop. This never returns. */
558 DEFUN ("kill-emacs", Fkill_emacs
, Skill_emacs
, 0, 1, "P",
559 "Exit the Emacs job and kill it. Ask for confirmation, without argument.\n\
560 If ARG is an integer, return ARG as the exit program code.\n\
561 If ARG is a string, stuff it as keyboard input.\n\n\
562 The value of `kill-emacs-hook', if not void,\n\
563 is a list of functions (of no args),\n\
564 all of which are called before Emacs is actually killed.")
568 Lisp_Object hook
, hook1
;
577 if (!NULL (Vrun_hooks
) && !noninteractive
)
578 call1 (Vrun_hooks
, intern ("kill-emacs-hook"));
581 kill_buffer_processes (Qnil
);
582 #endif /* subprocesses */
585 kill_vms_processes ();
588 Fdo_auto_save (Qt
, Qnil
);
590 #ifdef CLASH_DETECTION
592 #endif /* CLASH_DETECTION */
597 #ifdef HAVE_X_WINDOWS
598 if (!noninteractive
&& EQ (Vwindow_system
, intern ("x")))
599 Fx_close_current_connection ();
600 #endif /* HAVE_X_WINDOWS */
604 /* Is it really necessary to do this deassign
605 when we are going to exit anyway? */
609 stuff_buffered_input (arg
);
611 /* There is a tendency for a SIGIO signal to arrive within exit,
612 and cause a SIGHUP because the input descriptor is already closed. */
614 signal (SIGIO
, SIG_IGN
);
616 exit ((XTYPE (arg
) == Lisp_Int
) ? XINT (arg
)
627 /* Nothing like this can be implemented on an Apollo.
632 DEFUN ("dump-emacs-data", Fdump_emacs_data
, Sdump_emacs_data
, 1, 1, 0,
633 "Dump current state of Emacs into data file FILENAME.\n\
634 This function exists on systems that use HAVE_SHM.")
636 Lisp_Object intoname
;
640 extern void malloc_warning ();
642 CHECK_STRING (intoname
, 0);
643 intoname
= Fexpand_file_name (intoname
, Qnil
);
649 /* Tell malloc where start of impure now is */
650 /* Also arrange for warnings when nearly out of space. */
651 #ifndef SYSTEM_MALLOC
652 malloc_init (&my_edata
, malloc_warning
);
654 map_out_data (XSTRING (intoname
)->data
);
661 #else /* not HAVE_SHM */
663 DEFUN ("dump-emacs", Fdump_emacs
, Sdump_emacs
, 2, 2, 0,
664 "Dump current state of Emacs into executable file FILENAME.\n\
665 Take symbols from SYMFILE (presumably the file you executed to run Emacs).\n\
666 This is used in the file `loadup.el' when building Emacs.\n\
668 Bind `command-line-processed' to nil before dumping,\n\
669 if you want the dumped Emacs to process its command line\n\
670 and announce itself normally when it is run.")
672 Lisp_Object intoname
, symname
;
676 extern void malloc_warning ();
678 CHECK_STRING (intoname
, 0);
679 intoname
= Fexpand_file_name (intoname
, Qnil
);
682 CHECK_STRING (symname
, 0);
683 if (XSTRING (symname
)->size
)
684 symname
= Fexpand_file_name (symname
, Qnil
);
692 mapout_data (XSTRING (intoname
)->data
);
694 /* Tell malloc where start of impure now is */
695 /* Also arrange for warnings when nearly out of space. */
696 #ifndef SYSTEM_MALLOC
697 malloc_init (&my_edata
, malloc_warning
);
699 unexec (XSTRING (intoname
)->data
,
700 !NULL (symname
) ? XSTRING (symname
)->data
: 0, &my_edata
, 0, 0);
708 #endif /* not HAVE_SHM */
710 #endif /* not CANNOT_DUMP */
719 decode_env_path (evarname
, defalt
)
720 char *evarname
, *defalt
;
722 register char *path
, *p
;
723 extern char *index ();
727 path
= (char *) egetenv (evarname
);
733 p
= index (path
, SEPCHAR
);
734 if (!p
) p
= path
+ strlen (path
);
735 lpath
= Fcons (p
- path
? make_string (path
, p
- path
) : Qnil
,
742 return Fnreverse (lpath
);
748 defsubr (&Sdump_emacs_data
);
750 defsubr (&Sdump_emacs
);
753 defsubr (&Skill_emacs
);
755 DEFVAR_LISP ("command-line-args", &Vcommand_line_args
,
756 "Args passed by shell to Emacs, as a list of strings.");
758 DEFVAR_LISP ("system-type", &Vsystem_type
,
759 "Value is symbol indicating type of operating system you are using.");
760 Vsystem_type
= intern (SYSTEM_TYPE
);
762 DEFVAR_BOOL ("noninteractive", &noninteractive1
,
763 "Non-nil means Emacs is running without interactive terminal.");