]> code.delx.au - gnu-emacs/blob - src/emacs.c
(main) [MSDOS]: Call init_environment. Set file types to
[gnu-emacs] / src / emacs.c
1 /* Fully extensible Emacs, running on Unix, intended for GNU.
2 Copyright (C) 1985, 1986, 1987, 1993 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 #ifdef APOLLO
39 #ifndef APOLLO_SR10
40 #include <default_acl.h>
41 #endif
42 #endif
43
44 #include "lisp.h"
45 #include "commands.h"
46 #include "intervals.h"
47
48 #include "systty.h"
49 #include "syssignal.h"
50 #include "process.h"
51
52 #ifndef O_RDWR
53 #define O_RDWR 2
54 #endif
55
56 /* Command line args from shell, as list of strings */
57 Lisp_Object Vcommand_line_args;
58
59 /* The name under which Emacs was invoked, with any leading directory
60 names discarded. */
61 Lisp_Object Vinvocation_name;
62
63 /* The directory name from which Emacs was invoked. */
64 Lisp_Object Vinvocation_directory;
65
66 /* Hook run by `kill-emacs' before it does really anything. */
67 Lisp_Object Vkill_emacs_hook;
68
69 /* Set nonzero after Emacs has started up the first time.
70 Prevents reinitialization of the Lisp world and keymaps
71 on subsequent starts. */
72 int initialized;
73
74 /* Variable whose value is symbol giving operating system type. */
75 Lisp_Object Vsystem_type;
76
77 /* Variable whose value is string giving configuration built for. */
78 Lisp_Object Vsystem_configuration;
79
80 /* If non-zero, emacs should not attempt to use an window-specific code,
81 but instead should use the virtual terminal under which it was started */
82 int inhibit_window_system;
83
84 /* If nonzero, set Emacs to run at this priority. This is also used
85 in child_setup and sys_suspend to make sure subshells run at normal
86 priority; Those functions have their own extern declaration. */
87 int emacs_priority;
88
89 #ifdef BSD
90 /* See sysdep.c. */
91 extern int inherited_pgroup;
92 #endif
93
94 #ifdef HAVE_X_WINDOWS
95 /* If non-zero, -d was specified, meaning we're using some window system. */
96 int display_arg;
97 #endif
98
99 /* An address near the bottom of the stack.
100 Tells GC how to save a copy of the stack. */
101 char *stack_bottom;
102
103 #ifdef HAVE_X_WINDOWS
104 extern Lisp_Object Vwindow_system;
105 #endif /* HAVE_X_WINDOWS */
106
107 #ifdef USG_SHARED_LIBRARIES
108 /* If nonzero, this is the place to put the end of the writable segment
109 at startup. */
110
111 unsigned int bss_end = 0;
112 #endif
113
114 /* Nonzero means running Emacs without interactive terminal. */
115
116 int noninteractive;
117
118 /* Value of Lisp variable `noninteractive'.
119 Normally same as C variable `noninteractive'
120 but nothing terrible happens if user sets this one. */
121
122 int noninteractive1;
123 \f
124 /* Signal code for the fatal signal that was received */
125 int fatal_error_code;
126
127 /* Nonzero if handling a fatal error already */
128 int fatal_error_in_progress;
129
130 /* Handle bus errors, illegal instruction, etc. */
131 SIGTYPE
132 fatal_error_signal (sig)
133 int sig;
134 {
135 fatal_error_code = sig;
136 signal (sig, SIG_DFL);
137
138 /* If fatal error occurs in code below, avoid infinite recursion. */
139 if (! fatal_error_in_progress)
140 {
141 fatal_error_in_progress = 1;
142
143 shut_down_emacs (sig, 0, Qnil);
144 }
145
146 #ifdef VMS
147 LIB$STOP (SS$_ABORT);
148 #else
149 /* Signal the same code; this time it will really be fatal.
150 Remember that since we're in a signal handler, the signal we're
151 going to send is probably blocked, so we have to unblock it if we
152 want to really receive it. */
153 #ifndef MSDOS
154 sigunblock (sigmask (fatal_error_code));
155 #endif
156 kill (getpid (), fatal_error_code);
157 #endif /* not VMS */
158 }
159
160 #ifdef SIGDANGER
161
162 /* Handle bus errors, illegal instruction, etc. */
163 SIGTYPE
164 memory_warning_signal (sig)
165 int sig;
166 {
167 signal (sig, memory_warning_signal);
168
169 malloc_warning ("Operating system warns that virtual memory is running low.\n");
170 }
171 #endif
172 \f
173 /* Code for dealing with Lisp access to the Unix command line */
174
175 static
176 init_cmdargs (argc, argv, skip_args)
177 int argc;
178 char **argv;
179 int skip_args;
180 {
181 register int i;
182
183 Vinvocation_name = Ffile_name_nondirectory (build_string (argv[0]));
184 Vinvocation_directory = Ffile_name_directory (build_string (argv[0]));
185 /* If we got no directory in argv[0], search PATH to find where
186 Emacs actually came from. */
187 if (NILP (Vinvocation_directory))
188 {
189 Lisp_Object found;
190 int yes = openp (Vexec_path, Vinvocation_name,
191 EXEC_SUFFIXES, &found, 1);
192 if (yes == 1)
193 Vinvocation_directory = Ffile_name_directory (found);
194 }
195
196 Vcommand_line_args = Qnil;
197
198 for (i = argc - 1; i >= 0; i--)
199 {
200 if (i == 0 || i > skip_args)
201 Vcommand_line_args
202 = Fcons (build_string (argv[i]), Vcommand_line_args);
203 }
204 }
205
206 DEFUN ("invocation-name", Finvocation_name, Sinvocation_name, 0, 0, 0,
207 "Return the program name that was used to run Emacs.\n\
208 Any directory names are omitted.")
209 ()
210 {
211 return Fcopy_sequence (Vinvocation_name);
212 }
213
214 DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory,
215 0, 0, 0,
216 "Return the directory name in which the Emacs executable was located")
217 ()
218 {
219 return Fcopy_sequence (Vinvocation_directory);
220 }
221
222 \f
223 #ifdef VMS
224 #ifdef LINK_CRTL_SHARE
225 #ifdef SHAREABLE_LIB_BUG
226 extern noshare char **environ;
227 #endif /* SHAREABLE_LIB_BUG */
228 #endif /* LINK_CRTL_SHARE */
229 #endif /* VMS */
230
231 #ifndef ORDINARY_LINK
232 /* We don't include crtbegin.o and crtend.o in the link,
233 so these functions and variables might be missed.
234 Provide dummy definitions to avoid error.
235 (We don't have any real constructors or destructors.) */
236 #ifdef __GNUC__
237 __do_global_ctors ()
238 {}
239 __do_global_ctors_aux ()
240 {}
241 __do_global_dtors ()
242 {}
243 /* Linux has a bug in its library; avoid an error. */
244 #ifndef LINUX
245 char * __CTOR_LIST__[2] = { (char *) (-1), 0 };
246 #endif
247 char * __DTOR_LIST__[2] = { (char *) (-1), 0 };
248 __main ()
249 {}
250 #endif /* __GNUC__ */
251 #endif /* ORDINARY_LINK */
252
253 /* ARGSUSED */
254 main (argc, argv, envp)
255 int argc;
256 char **argv;
257 char **envp;
258 {
259 char stack_bottom_variable;
260 int skip_args = 0;
261 extern int errno;
262 extern sys_nerr;
263 extern char *sys_errlist[];
264 extern void malloc_warning ();
265
266 /* Map in shared memory, if we are using that. */
267 #ifdef HAVE_SHM
268 if (argc > 1 && !strcmp (argv[1], "-nl"))
269 {
270 map_in_data (0);
271 /* The shared memory was just restored, which clobbered this. */
272 skip_args = 1;
273 }
274 else
275 {
276 map_in_data (1);
277 /* The shared memory was just restored, which clobbered this. */
278 skip_args = 0;
279 }
280 #endif
281
282 #ifdef NeXT
283 extern int malloc_cookie;
284
285 /* This helps out unexnext.c. */
286 if (initialized)
287 if (malloc_jumpstart (malloc_cookie) != 0)
288 printf ("malloc jumpstart failed!\n");
289 #endif /* NeXT */
290
291 #ifdef HAVE_X_WINDOWS
292 /* Stupid kludge to catch command-line display spec. We can't
293 handle this argument entirely in window system dependent code
294 because we don't even know which window system dependent code
295 to run until we've recognized this argument. */
296 {
297 int i;
298
299 for (i = 1; (i < argc && ! display_arg); i++)
300 if (!strcmp (argv[i], "-d") || !strcmp (argv[i], "-display"))
301 display_arg = 1;
302 }
303 #endif
304
305 #ifdef VMS
306 /* If -map specified, map the data file in */
307 if (argc > 2 && ! strcmp (argv[1], "-map"))
308 {
309 skip_args = 2;
310 mapin_data (argv[2]);
311 }
312
313 #ifdef LINK_CRTL_SHARE
314 #ifdef SHAREABLE_LIB_BUG
315 /* Bletcherous shared libraries! */
316 if (!stdin)
317 stdin = fdopen (0, "r");
318 if (!stdout)
319 stdout = fdopen (1, "w");
320 if (!stderr)
321 stderr = fdopen (2, "w");
322 if (!environ)
323 environ = envp;
324 #endif /* SHAREABLE_LIB_BUG */
325 #endif /* LINK_CRTL_SHARE */
326 #endif /* VMS */
327
328 /* Record (approximately) where the stack begins. */
329 stack_bottom = &stack_bottom_variable;
330
331 #ifdef RUN_TIME_REMAP
332 if (initialized)
333 run_time_remap (argv[0]);
334 #endif
335
336 #ifdef USG_SHARED_LIBRARIES
337 if (bss_end)
338 brk (bss_end);
339 #endif
340
341 clearerr (stdin);
342
343 #ifdef BSD
344 {
345 inherited_pgroup = EMACS_GETPGRP (0);
346 setpgrp (0, getpid ());
347 }
348 #endif
349
350
351 #ifdef APOLLO
352 #ifndef APOLLO_SR10
353 /* If USE_DOMAIN_ACLS environment variable exists,
354 use ACLs rather than UNIX modes. */
355 if (egetenv ("USE_DOMAIN_ACLS"))
356 default_acl (USE_DEFACL);
357 #endif
358 #endif /* APOLLO */
359
360 #ifndef SYSTEM_MALLOC
361 if (! initialized)
362 {
363 /* Arrange to get warning messages as memory fills up. */
364 memory_warnings (0, malloc_warning);
365
366 /* Arrange to disable interrupt input while malloc and friends are
367 running. */
368 uninterrupt_malloc ();
369 }
370 #endif /* not SYSTEM_MALLOC */
371
372 #ifdef MSDOS
373 /* We do all file input/output as binary files. When we need to translate
374 newlines, we do that manually. */
375 _fmode = O_BINARY;
376 (stdin)->_flag &= ~_IOTEXT;
377 (stdout)->_flag &= ~_IOTEXT;
378 (stderr)->_flag &= ~_IOTEXT;
379 #endif /* MSDOS */
380
381 #ifdef PRIO_PROCESS
382 if (emacs_priority)
383 nice (emacs_priority);
384 setuid (getuid ());
385 #endif /* PRIO_PROCESS */
386
387 inhibit_window_system = 0;
388
389 /* Handle the -t switch, which specifies filename to use as terminal */
390 if (skip_args + 2 < argc && !strcmp (argv[skip_args + 1], "-t"))
391 {
392 int result;
393 skip_args += 2;
394 close (0);
395 close (1);
396 result = open (argv[skip_args], O_RDWR, 2 );
397 if (result < 0)
398 {
399 char *errstring;
400
401 if (errno >= 0 && errno < sys_nerr)
402 errstring = sys_errlist[errno];
403 else
404 errstring = "undocumented error code";
405 fprintf (stderr, "emacs: %s: %s\n", argv[skip_args], errstring);
406 exit (1);
407 }
408 dup (0);
409 if (! isatty (0))
410 {
411 fprintf (stderr, "emacs: %s: not a tty\n", argv[skip_args]);
412 exit (1);
413 }
414 fprintf (stderr, "Using %s\n", argv[skip_args]);
415 #ifdef HAVE_X_WINDOWS
416 inhibit_window_system = 1; /* -t => -nw */
417 #endif
418 }
419
420 if (skip_args + 1 < argc
421 && (!strcmp (argv[skip_args + 1], "-nw")))
422 {
423 skip_args += 1;
424 inhibit_window_system = 1;
425 }
426
427 /* Handle the -batch switch, which means don't do interactive display. */
428 noninteractive = 0;
429 if (skip_args + 1 < argc && !strcmp (argv[skip_args + 1], "-batch"))
430 {
431 skip_args += 1;
432 noninteractive = 1;
433 }
434
435 #ifdef POSIX_SIGNALS
436 init_signals ();
437 #endif
438
439 if (
440 #ifndef CANNOT_DUMP
441 ! noninteractive || initialized
442 #else
443 1
444 #endif
445 )
446 {
447 /* Don't catch these signals in batch mode if not initialized.
448 On some machines, this sets static data that would make
449 signal fail to work right when the dumped Emacs is run. */
450 signal (SIGHUP, fatal_error_signal);
451 signal (SIGQUIT, fatal_error_signal);
452 signal (SIGILL, fatal_error_signal);
453 signal (SIGTRAP, fatal_error_signal);
454 #ifdef SIGIOT
455 /* This is missing on some systems - OS/2, for example. */
456 signal (SIGIOT, fatal_error_signal);
457 #endif
458 #ifdef SIGEMT
459 signal (SIGEMT, fatal_error_signal);
460 #endif
461 signal (SIGFPE, fatal_error_signal);
462 #ifdef SIGBUS
463 signal (SIGBUS, fatal_error_signal);
464 #endif
465 signal (SIGSEGV, fatal_error_signal);
466 #ifdef SIGSYS
467 signal (SIGSYS, fatal_error_signal);
468 #endif
469 signal (SIGTERM, fatal_error_signal);
470 #ifdef SIGXCPU
471 signal (SIGXCPU, fatal_error_signal);
472 #endif
473 #ifdef SIGXFSZ
474 signal (SIGXFSZ, fatal_error_signal);
475 #endif /* SIGXFSZ */
476
477 #ifdef SIGDANGER
478 /* This just means available memory is getting low. */
479 signal (SIGDANGER, memory_warning_signal);
480 #endif
481
482 #ifdef AIX
483 signal (20, fatal_error_signal);
484 signal (21, fatal_error_signal);
485 signal (22, fatal_error_signal);
486 signal (24, fatal_error_signal);
487 #if 0 /* mvn@library.ucla.edu says these are SIGIO on AIX 3.2.4. */
488 signal (23, fatal_error_signal);
489 #ifdef SIGIO
490 signal (SIGAIO, fatal_error_signal);
491 signal (SIGPTY, fatal_error_signal);
492 #endif
493 #endif
494 #ifndef _I386
495 signal (SIGIOINT, fatal_error_signal);
496 #endif
497 signal (SIGGRANT, fatal_error_signal);
498 signal (SIGRETRACT, fatal_error_signal);
499 signal (SIGSOUND, fatal_error_signal);
500 signal (SIGMSG, fatal_error_signal);
501 #endif /* AIX */
502 }
503
504 noninteractive1 = noninteractive;
505
506 /* Perform basic initializations (not merely interning symbols) */
507
508 if (!initialized)
509 {
510 init_alloc_once ();
511 init_obarray ();
512 init_eval_once ();
513 init_syntax_once (); /* Create standard syntax table. */
514 /* Must be done before init_buffer */
515 init_casetab_once ();
516 init_buffer_once (); /* Create buffer table and some buffers */
517 init_minibuf_once (); /* Create list of minibuffers */
518 /* Must precede init_window_once */
519 init_window_once (); /* Init the window system */
520 }
521
522 init_alloc ();
523 init_eval ();
524 init_data ();
525
526 #ifdef MSDOS
527 /* Call early 'cause init_environment needs it. */
528 init_dosfns ();
529 /* Set defaults for several environment variables. */
530 if (initialized) init_environment (argc, argv, skip_args);
531 #endif
532
533 /* egetenv is a pretty low-level facility, which may get called in
534 many circumstances; it seems flimsy to put off initializing it
535 until calling init_callproc. */
536 set_process_environment ();
537 /* AIX crashes are reported in system versions 3.2.3 and 3.2.4
538 if this is not done. Do it after set_process_environment so that we
539 don't pollute Vprocess_environment. */
540 #ifdef AIX
541 putenv ("LANG=C");
542 #endif
543
544 init_buffer (); /* Init default directory of main buffer */
545
546 init_callproc_1 (); /* Must precede init_cmdargs and init_sys_modes. */
547 init_cmdargs (argc, argv, skip_args); /* Must precede init_lread. */
548 init_callproc (); /* Must follow init_cmdargs but not init_sys_modes. */
549 init_lread ();
550
551 if (!noninteractive)
552 {
553 #ifdef VMS
554 init_vms_input ();/* init_display calls get_frame_size, that needs this */
555 #endif /* VMS */
556 init_display (); /* Determine terminal type. init_sys_modes uses results */
557 }
558 init_keyboard (); /* This too must precede init_sys_modes */
559 #ifdef VMS
560 init_vmsproc (); /* And this too. */
561 #endif /* VMS */
562 init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.) */
563 init_xdisp ();
564 init_macros ();
565 init_editfns ();
566 #ifdef LISP_FLOAT_TYPE
567 init_floatfns ();
568 #endif
569 #ifdef VMS
570 init_vmsfns ();
571 #endif /* VMS */
572 init_process ();
573 #ifdef CLASH_DETECTION
574 init_filelock ();
575 #endif /* CLASH_DETECTION */
576
577 /* Intern the names of all standard functions and variables; define standard keys */
578
579 if (!initialized)
580 {
581 /* The basic levels of Lisp must come first */
582 /* And data must come first of all
583 for the sake of symbols like error-message */
584 syms_of_data ();
585 syms_of_alloc ();
586 syms_of_lread ();
587 syms_of_print ();
588 syms_of_eval ();
589 syms_of_fns ();
590 syms_of_floatfns ();
591
592 syms_of_abbrev ();
593 syms_of_buffer ();
594 syms_of_bytecode ();
595 syms_of_callint ();
596 syms_of_casefiddle ();
597 syms_of_casetab ();
598 syms_of_callproc ();
599 syms_of_cmds ();
600 #ifndef NO_DIR_LIBRARY
601 syms_of_dired ();
602 #endif /* not NO_DIR_LIBRARY */
603 syms_of_display ();
604 syms_of_doc ();
605 syms_of_editfns ();
606 syms_of_emacs ();
607 syms_of_fileio ();
608 #ifdef CLASH_DETECTION
609 syms_of_filelock ();
610 #endif /* CLASH_DETECTION */
611 syms_of_indent ();
612 syms_of_keyboard ();
613 syms_of_keymap ();
614 syms_of_macros ();
615 syms_of_marker ();
616 syms_of_minibuf ();
617 syms_of_mocklisp ();
618 syms_of_process ();
619 syms_of_search ();
620 syms_of_frame ();
621 syms_of_syntax ();
622 syms_of_undo ();
623
624 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
625 syms_of_textprop ();
626 #ifdef VMS
627 syms_of_vmsproc ();
628 #endif /* VMS */
629 syms_of_window ();
630 syms_of_xdisp ();
631 #ifdef HAVE_X_WINDOWS
632 syms_of_xterm ();
633 syms_of_xfns ();
634 syms_of_xfaces ();
635 #ifdef HAVE_X11
636 syms_of_xselect ();
637 #endif
638 #ifdef HAVE_X_MENU
639 syms_of_xmenu ();
640 #endif /* HAVE_X_MENU */
641 #endif /* HAVE_X_WINDOWS */
642
643 #ifdef SYMS_SYSTEM
644 SYMS_SYSTEM;
645 #endif
646
647 #ifdef SYMS_MACHINE
648 SYMS_MACHINE;
649 #endif
650
651 keys_of_casefiddle ();
652 keys_of_cmds ();
653 keys_of_buffer ();
654 keys_of_keyboard ();
655 keys_of_keymap ();
656 keys_of_macros ();
657 keys_of_minibuf ();
658 keys_of_window ();
659 keys_of_frame ();
660 }
661
662 if (!initialized)
663 {
664 /* Handle -l loadup-and-dump, args passed by Makefile. */
665 if (argc > 2 + skip_args && !strcmp (argv[1 + skip_args], "-l"))
666 Vtop_level = Fcons (intern ("load"),
667 Fcons (build_string (argv[2 + skip_args]), Qnil));
668 #ifdef CANNOT_DUMP
669 /* Unless next switch is -nl, load "loadup.el" first thing. */
670 if (!(argc > 1 + skip_args && !strcmp (argv[1 + skip_args], "-nl")))
671 Vtop_level = Fcons (intern ("load"),
672 Fcons (build_string ("loadup.el"), Qnil));
673 #endif /* CANNOT_DUMP */
674 }
675
676 initialized = 1;
677
678 #if defined (sun) || defined (LOCALTIME_CACHE)
679 /* sun's localtime has a bug. it caches the value of the time
680 zone rather than looking it up every time. Since localtime() is
681 called to bolt the undumping time into the undumped emacs, this
682 results in localtime ignoring the TZ environment variable.
683 This flushes the new TZ value into localtime. */
684 tzset ();
685 #endif /* defined (sun) || defined (LOCALTIME_CACHE) */
686
687 /* Enter editor command loop. This never returns. */
688 Frecursive_edit ();
689 /* NOTREACHED */
690 }
691 \f
692 DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P",
693 "Exit the Emacs job and kill it.\n\
694 If ARG is an integer, return ARG as the exit program code.\n\
695 If ARG is a string, stuff it as keyboard input.\n\n\
696 The value of `kill-emacs-hook', if not void,\n\
697 is a list of functions (of no args),\n\
698 all of which are called before Emacs is actually killed.")
699 (arg)
700 Lisp_Object arg;
701 {
702 Lisp_Object hook, hook1;
703 int i;
704 struct gcpro gcpro1;
705
706 GCPRO1 (arg);
707
708 if (feof (stdin))
709 arg = Qt;
710
711 if (!NILP (Vrun_hooks) && !noninteractive)
712 call1 (Vrun_hooks, intern ("kill-emacs-hook"));
713
714 UNGCPRO;
715
716 /* Is it really necessary to do this deassign
717 when we are going to exit anyway? */
718 /* #ifdef VMS
719 stop_vms_input ();
720 #endif */
721
722 shut_down_emacs (0, 0, STRINGP (arg) ? arg : Qnil);
723
724 exit ((XTYPE (arg) == Lisp_Int) ? XINT (arg)
725 #ifdef VMS
726 : 1
727 #else
728 : 0
729 #endif
730 );
731 /* NOTREACHED */
732 }
733
734
735 /* Perform an orderly shutdown of Emacs. Autosave any modified
736 buffers, kill any child processes, clean up the terminal modes (if
737 we're in the foreground), and other stuff like that. Don't perform
738 any redisplay; this may be called when Emacs is shutting down in
739 the background, or after its X connection has died.
740
741 If SIG is a signal number, print a message for it.
742
743 This is called by fatal signal handlers, X protocol error handlers,
744 and Fkill_emacs. */
745
746 void
747 shut_down_emacs (sig, no_x, stuff)
748 int sig, no_x;
749 Lisp_Object stuff;
750 {
751 /* If we are controlling the terminal, reset terminal modes */
752 #ifdef EMACS_HAVE_TTY_PGRP
753 {
754 int pgrp = EMACS_GETPGRP (0);
755
756 int tpgrp;
757 if (EMACS_GET_TTY_PGRP (0, &tpgrp) != -1
758 && tpgrp == pgrp)
759 {
760 fflush (stdout);
761 reset_sys_modes ();
762 if (sig && sig != SIGTERM)
763 fprintf (stderr, "Fatal error (%d).", sig);
764 }
765 }
766 #else
767 fflush (stdout);
768 reset_sys_modes ();
769 #endif
770
771 stuff_buffered_input (stuff);
772
773 kill_buffer_processes (Qnil);
774 Fdo_auto_save (Qt, Qnil);
775
776 #ifdef CLASH_DETECTION
777 unlock_all_files ();
778 #endif
779
780 #ifdef VMS
781 kill_vms_processes ();
782 #endif
783
784 #ifdef HAVE_X_WINDOWS
785 if (!noninteractive && EQ (Vwindow_system, intern ("x")) && ! no_x)
786 Fx_close_current_connection ();
787 #endif /* HAVE_X_WINDOWS */
788
789 #ifdef SIGIO
790 /* There is a tendency for a SIGIO signal to arrive within exit,
791 and cause a SIGHUP because the input descriptor is already closed. */
792 unrequest_sigio ();
793 signal (SIGIO, SIG_IGN);
794 #endif
795 }
796
797
798 \f
799 #ifndef CANNOT_DUMP
800 /* Nothing like this can be implemented on an Apollo.
801 What a loss! */
802
803 #ifdef HAVE_SHM
804
805 DEFUN ("dump-emacs-data", Fdump_emacs_data, Sdump_emacs_data, 1, 1, 0,
806 "Dump current state of Emacs into data file FILENAME.\n\
807 This function exists on systems that use HAVE_SHM.")
808 (intoname)
809 Lisp_Object intoname;
810 {
811 extern int my_edata;
812 Lisp_Object tem;
813 extern void malloc_warning ();
814
815 CHECK_STRING (intoname, 0);
816 intoname = Fexpand_file_name (intoname, Qnil);
817
818 tem = Vpurify_flag;
819 Vpurify_flag = Qnil;
820
821 fflush (stdout);
822 /* Tell malloc where start of impure now is */
823 /* Also arrange for warnings when nearly out of space. */
824 #ifndef SYSTEM_MALLOC
825 memory_warnings (&my_edata, malloc_warning);
826 #endif
827 map_out_data (XSTRING (intoname)->data);
828
829 Vpurify_flag = tem;
830
831 return Qnil;
832 }
833
834 #else /* not HAVE_SHM */
835
836 DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0,
837 "Dump current state of Emacs into executable file FILENAME.\n\
838 Take symbols from SYMFILE (presumably the file you executed to run Emacs).\n\
839 This is used in the file `loadup.el' when building Emacs.\n\
840 \n\
841 Bind `command-line-processed' to nil before dumping,\n\
842 if you want the dumped Emacs to process its command line\n\
843 and announce itself normally when it is run.")
844 (intoname, symname)
845 Lisp_Object intoname, symname;
846 {
847 extern int my_edata;
848 Lisp_Object tem;
849 extern void malloc_warning ();
850
851 CHECK_STRING (intoname, 0);
852 intoname = Fexpand_file_name (intoname, Qnil);
853 if (!NILP (symname))
854 {
855 CHECK_STRING (symname, 0);
856 if (XSTRING (symname)->size)
857 symname = Fexpand_file_name (symname, Qnil);
858 }
859
860 tem = Vpurify_flag;
861 Vpurify_flag = Qnil;
862
863 fflush (stdout);
864 #ifdef VMS
865 mapout_data (XSTRING (intoname)->data);
866 #else
867 /* Tell malloc where start of impure now is */
868 /* Also arrange for warnings when nearly out of space. */
869 #ifndef SYSTEM_MALLOC
870 memory_warnings (&my_edata, malloc_warning);
871 #endif
872 unexec (XSTRING (intoname)->data,
873 !NILP (symname) ? XSTRING (symname)->data : 0, &my_edata, 0, 0);
874 #endif /* not VMS */
875
876 Vpurify_flag = tem;
877
878 return Qnil;
879 }
880
881 #endif /* not HAVE_SHM */
882
883 #endif /* not CANNOT_DUMP */
884 \f
885 #ifndef SEPCHAR
886 #define SEPCHAR ':'
887 #endif
888
889 Lisp_Object
890 decode_env_path (evarname, defalt)
891 char *evarname, *defalt;
892 {
893 register char *path, *p;
894 extern char *index ();
895
896 Lisp_Object lpath;
897
898 /* It's okay to use getenv here, because this function is only used
899 to initialize variables when Emacs starts up, and isn't called
900 after that. */
901 if (evarname != 0)
902 path = (char *) getenv (evarname);
903 else
904 path = 0;
905 if (!path)
906 path = defalt;
907 lpath = Qnil;
908 while (1)
909 {
910 p = index (path, SEPCHAR);
911 if (!p) p = path + strlen (path);
912 lpath = Fcons (p - path ? make_string (path, p - path) : Qnil,
913 lpath);
914 if (*p)
915 path = p + 1;
916 else
917 break;
918 }
919 return Fnreverse (lpath);
920 }
921
922 syms_of_emacs ()
923 {
924 #ifndef CANNOT_DUMP
925 #ifdef HAVE_SHM
926 defsubr (&Sdump_emacs_data);
927 #else
928 defsubr (&Sdump_emacs);
929 #endif
930 #endif
931
932 defsubr (&Skill_emacs);
933
934 defsubr (&Sinvocation_name);
935 defsubr (&Sinvocation_directory);
936
937 DEFVAR_LISP ("command-line-args", &Vcommand_line_args,
938 "Args passed by shell to Emacs, as a list of strings.");
939
940 DEFVAR_LISP ("system-type", &Vsystem_type,
941 "Value is symbol indicating type of operating system you are using.");
942 Vsystem_type = intern (SYSTEM_TYPE);
943
944 DEFVAR_LISP ("system-configuration", &Vsystem_configuration,
945 "Value is string indicating configuration Emacs was built for.");
946 Vsystem_configuration = build_string (CONFIGURATION);
947
948 DEFVAR_BOOL ("noninteractive", &noninteractive1,
949 "Non-nil means Emacs is running without interactive terminal.");
950
951 DEFVAR_LISP ("kill-emacs-hook", &Vkill_emacs_hook,
952 "Hook to be run whenever kill-emacs is called.\n\
953 Since kill-emacs may be invoked when the terminal is disconnected (or\n\
954 in other similar situations), functions placed on this hook should not\n\
955 expect to be able to interact with the user.");
956 Vkill_emacs_hook = Qnil;
957
958 DEFVAR_INT ("emacs-priority", &emacs_priority,
959 "Priority for Emacs to run at.\n\
960 This value is effective only if set before Emacs is dumped,\n\
961 and only if the Emacs executable is installed with setuid to permit\n\
962 it to change priority. (Emacs sets its uid back to the real uid.)");
963 emacs_priority = 0;
964
965 staticpro (&Vinvocation_name);
966 Vinvocation_name = Qnil;
967 staticpro (&Vinvocation_directory);
968 Vinvocation_directory = Qnil;
969 }