1*59813Shibler /* Fully extensible Emacs, running on Unix, intended for GNU. 2*59813Shibler Copyright (C) 1985, 1986, 1987, 1990 Free Software Foundation, Inc. 3*59813Shibler 4*59813Shibler This file is part of GNU Emacs. 5*59813Shibler 6*59813Shibler GNU Emacs is free software; you can redistribute it and/or modify 7*59813Shibler it under the terms of the GNU General Public License as published by 8*59813Shibler the Free Software Foundation; either version 1, or (at your option) 9*59813Shibler any later version. 10*59813Shibler 11*59813Shibler GNU Emacs is distributed in the hope that it will be useful, 12*59813Shibler but WITHOUT ANY WARRANTY; without even the implied warranty of 13*59813Shibler MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*59813Shibler GNU General Public License for more details. 15*59813Shibler 16*59813Shibler You should have received a copy of the GNU General Public License 17*59813Shibler along with GNU Emacs; see the file COPYING. If not, write to 18*59813Shibler the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 19*59813Shibler 20*59813Shibler 21*59813Shibler #include <signal.h> 22*59813Shibler #include <errno.h> 23*59813Shibler 24*59813Shibler #include "config.h" 25*59813Shibler #include <stdio.h> 26*59813Shibler #undef NULL 27*59813Shibler #include "lisp.h" 28*59813Shibler #include "commands.h" 29*59813Shibler 30*59813Shibler #include <sys/types.h> 31*59813Shibler #include <sys/file.h> 32*59813Shibler 33*59813Shibler #ifdef VMS 34*59813Shibler #include <ssdef.h> 35*59813Shibler #endif 36*59813Shibler 37*59813Shibler #ifdef USG5 38*59813Shibler #include <fcntl.h> 39*59813Shibler #endif 40*59813Shibler 41*59813Shibler #ifdef BSD 42*59813Shibler #include <sys/ioctl.h> 43*59813Shibler #endif 44*59813Shibler 45*59813Shibler #ifdef APOLLO 46*59813Shibler #ifndef APOLLO_SR10 47*59813Shibler #include <default_acl.h> 48*59813Shibler #endif 49*59813Shibler #endif 50*59813Shibler 51*59813Shibler #ifndef O_RDWR 52*59813Shibler #define O_RDWR 2 53*59813Shibler #endif 54*59813Shibler 55*59813Shibler #define PRIO_PROCESS 0 56*59813Shibler 57*59813Shibler /* Command line args from shell, as list of strings */ 58*59813Shibler Lisp_Object Vcommand_line_args; 59*59813Shibler 60*59813Shibler /* Hook run by `kill-emacs' before it does really anything. */ 61*59813Shibler Lisp_Object Vkill_emacs_hook; 62*59813Shibler 63*59813Shibler /* Set nonzero after Emacs has started up the first time. 64*59813Shibler Prevents reinitialization of the Lisp world and keymaps 65*59813Shibler on subsequent starts. */ 66*59813Shibler int initialized; 67*59813Shibler 68*59813Shibler /* Variable whose value is symbol giving operating system type */ 69*59813Shibler Lisp_Object Vsystem_type; 70*59813Shibler 71*59813Shibler /* If non-zero, emacs should not attempt to use an window-specific code, 72*59813Shibler but instead should use the virtual terminal under which it was started */ 73*59813Shibler int inhibit_window_system; 74*59813Shibler 75*59813Shibler #ifdef HAVE_X_WINDOWS 76*59813Shibler /* If -d option is used, this variable points to the name of 77*59813Shibler the display to use. */ 78*59813Shibler char *alternate_display; 79*59813Shibler char **xargv; 80*59813Shibler int xargc; 81*59813Shibler #endif /* HAVE_X_WINDOWS */ 82*59813Shibler 83*59813Shibler #ifdef USG_SHARED_LIBRARIES 84*59813Shibler /* If nonzero, this is the place to put the end of the writable segment 85*59813Shibler at startup. */ 86*59813Shibler 87*59813Shibler unsigned int bss_end = 0; 88*59813Shibler #endif 89*59813Shibler 90*59813Shibler /* Nonzero means running Emacs without interactive terminal. */ 91*59813Shibler 92*59813Shibler int noninteractive; 93*59813Shibler 94*59813Shibler /* Value of Lisp variable `noninteractive'. 95*59813Shibler Normally same as C variable `noninteractive' 96*59813Shibler but nothing terrible happens if user sets this one. */ 97*59813Shibler 98*59813Shibler int noninteractive1; 99*59813Shibler 100*59813Shibler /* Signal code for the fatal signal that was received */ 101*59813Shibler int fatal_error_code; 102*59813Shibler 103*59813Shibler /* Nonzero if handling a fatal error already */ 104*59813Shibler int fatal_error_in_progress; 105*59813Shibler 106*59813Shibler /* Handle bus errors, illegal instruction, etc. */ 107*59813Shibler fatal_error_signal (sig) 108*59813Shibler int sig; 109*59813Shibler { 110*59813Shibler #ifdef BSD 111*59813Shibler int tpgrp; 112*59813Shibler #endif /* BSD */ 113*59813Shibler 114*59813Shibler fatal_error_code = sig; 115*59813Shibler signal (sig, SIG_DFL); 116*59813Shibler 117*59813Shibler /* If fatal error occurs in code below, avoid infinite recursion. */ 118*59813Shibler if (fatal_error_in_progress) 119*59813Shibler kill (getpid (), fatal_error_code); 120*59813Shibler 121*59813Shibler fatal_error_in_progress = 1; 122*59813Shibler 123*59813Shibler /* If we are controlling the terminal, reset terminal modes */ 124*59813Shibler #ifdef BSD 125*59813Shibler if (ioctl(0, TIOCGPGRP, &tpgrp) == 0 126*59813Shibler && tpgrp == getpgrp (0)) 127*59813Shibler #endif /* BSD */ 128*59813Shibler { 129*59813Shibler reset_sys_modes (); 130*59813Shibler if (sig != SIGTERM) 131*59813Shibler fprintf (stderr, "Fatal error (%d).", sig); 132*59813Shibler } 133*59813Shibler 134*59813Shibler /* Clean up */ 135*59813Shibler #ifdef subprocesses 136*59813Shibler kill_buffer_processes (Qnil); 137*59813Shibler #endif 138*59813Shibler Fdo_auto_save (Qt); 139*59813Shibler 140*59813Shibler #ifdef CLASH_DETECTION 141*59813Shibler unlock_all_files (); 142*59813Shibler #endif /* CLASH_DETECTION */ 143*59813Shibler 144*59813Shibler #ifdef VMS 145*59813Shibler kill_vms_processes (); 146*59813Shibler LIB$STOP (SS$_ABORT); 147*59813Shibler #else 148*59813Shibler /* Signal the same code; this time it will really be fatal. */ 149*59813Shibler kill (getpid (), fatal_error_code); 150*59813Shibler #endif /* not VMS */ 151*59813Shibler } 152*59813Shibler 153*59813Shibler /* Code for dealing with Lisp access to the Unix command line */ 154*59813Shibler 155*59813Shibler static 156*59813Shibler init_cmdargs (argc, argv, skip_args) 157*59813Shibler int argc; 158*59813Shibler char **argv; 159*59813Shibler int skip_args; 160*59813Shibler { 161*59813Shibler register int i; 162*59813Shibler 163*59813Shibler Vcommand_line_args = Qnil; 164*59813Shibler 165*59813Shibler for (i = argc - 1; i >= 0; i--) 166*59813Shibler { 167*59813Shibler if (i == 0 || i > skip_args) 168*59813Shibler Vcommand_line_args 169*59813Shibler = Fcons (build_string (argv[i]), Vcommand_line_args); 170*59813Shibler } 171*59813Shibler } 172*59813Shibler 173*59813Shibler #ifdef VMS 174*59813Shibler #ifdef LINK_CRTL_SHARE 175*59813Shibler #ifdef SHAREABLE_LIB_BUG 176*59813Shibler extern noshare char **environ; 177*59813Shibler #endif /* SHAREABLE_LIB_BUG */ 178*59813Shibler #endif /* LINK_CRTL_SHARE */ 179*59813Shibler #endif /* VMS */ 180*59813Shibler 181*59813Shibler /* ARGSUSED */ 182*59813Shibler main (argc, argv, envp) 183*59813Shibler int argc; 184*59813Shibler char **argv; 185*59813Shibler char **envp; 186*59813Shibler { 187*59813Shibler int skip_args = 0; 188*59813Shibler extern int errno; 189*59813Shibler extern void malloc_warning (); 190*59813Shibler 191*59813Shibler /* Map in shared memory, if we are using that. */ 192*59813Shibler #ifdef HAVE_SHM 193*59813Shibler if (argc > 1 && !strcmp (argv[1], "-nl")) 194*59813Shibler { 195*59813Shibler map_in_data (0); 196*59813Shibler /* The shared momory was just restored, which clobbered this. */ 197*59813Shibler skip_args = 1; 198*59813Shibler } 199*59813Shibler else 200*59813Shibler { 201*59813Shibler map_in_data (1); 202*59813Shibler /* The shared momory was just restored, which clobbered this. */ 203*59813Shibler skip_args = 0; 204*59813Shibler } 205*59813Shibler #endif 206*59813Shibler 207*59813Shibler #ifdef VMS 208*59813Shibler /* If -map specified, map the data file in */ 209*59813Shibler if (argc > 2 && ! strcmp (argv[1], "-map")) 210*59813Shibler { 211*59813Shibler skip_args = 2; 212*59813Shibler mapin_data (argv[2]); 213*59813Shibler } 214*59813Shibler 215*59813Shibler #ifdef LINK_CRTL_SHARE 216*59813Shibler #ifdef SHAREABLE_LIB_BUG 217*59813Shibler /* Bletcherous shared libraries! */ 218*59813Shibler if (!stdin) 219*59813Shibler stdin = fdopen (0, "r"); 220*59813Shibler if (!stdout) 221*59813Shibler stdout = fdopen (1, "w"); 222*59813Shibler if (!stderr) 223*59813Shibler stderr = fdopen (2, "w"); 224*59813Shibler if (!environ) 225*59813Shibler environ = envp; 226*59813Shibler #endif /* SHAREABLE_LIB_BUG */ 227*59813Shibler #endif /* LINK_CRTL_SHARE */ 228*59813Shibler #endif /* VMS */ 229*59813Shibler 230*59813Shibler #ifdef USG_SHARED_LIBRARIES 231*59813Shibler if (bss_end) 232*59813Shibler brk (bss_end); 233*59813Shibler #endif 234*59813Shibler 235*59813Shibler clearerr (stdin); 236*59813Shibler 237*59813Shibler #ifdef APOLLO 238*59813Shibler #ifndef APOLLO_SR10 239*59813Shibler /* If USE_DOMAIN_ACLS environment variable exists, 240*59813Shibler use ACLs rather than UNIX modes. */ 241*59813Shibler if (egetenv ("USE_DOMAIN_ACLS")) 242*59813Shibler default_acl (USE_DEFACL); 243*59813Shibler #endif 244*59813Shibler #endif /* APOLLO */ 245*59813Shibler 246*59813Shibler #ifndef SYSTEM_MALLOC 247*59813Shibler /* Arrange for warnings when nearly out of space. */ 248*59813Shibler malloc_init (0, malloc_warning); 249*59813Shibler #endif 250*59813Shibler 251*59813Shibler #ifdef HIGHPRI 252*59813Shibler setpriority (PRIO_PROCESS, getpid (), HIGHPRI); 253*59813Shibler setuid (getuid ()); 254*59813Shibler #endif HIGHPRI 255*59813Shibler 256*59813Shibler inhibit_window_system = 0; 257*59813Shibler 258*59813Shibler #ifdef HAVE_X_WINDOWS 259*59813Shibler xargv = argv; 260*59813Shibler xargc = argc; 261*59813Shibler #endif 262*59813Shibler 263*59813Shibler /* Handle the -t switch, which specifies filename to use as terminal */ 264*59813Shibler if (skip_args + 2 < argc && !strcmp (argv[skip_args + 1], "-t")) 265*59813Shibler { 266*59813Shibler skip_args += 2; 267*59813Shibler close (0); 268*59813Shibler close (1); 269*59813Shibler open (argv[skip_args], O_RDWR, 2 ); 270*59813Shibler dup (0); 271*59813Shibler fprintf (stderr, "Using %s\n", argv[skip_args]); 272*59813Shibler #ifdef HAVE_X_WINDOWS 273*59813Shibler inhibit_window_system = 1; /* -t => -nw */ 274*59813Shibler #endif 275*59813Shibler } 276*59813Shibler #ifdef HAVE_X_WINDOWS 277*59813Shibler /* Handle the -d switch, which means use a different display for X */ 278*59813Shibler if (skip_args + 2 < argc && (!strcmp (argv[skip_args + 1], "-d") || 279*59813Shibler !strcmp (argv[skip_args + 1], "-display"))) 280*59813Shibler { 281*59813Shibler skip_args += 2; 282*59813Shibler alternate_display = argv[skip_args]; 283*59813Shibler } 284*59813Shibler else 285*59813Shibler alternate_display = 0; 286*59813Shibler #endif /* HAVE_X_WINDOWS */ 287*59813Shibler 288*59813Shibler if (skip_args + 1 < argc 289*59813Shibler && (!strcmp (argv[skip_args + 1], "-nw"))) 290*59813Shibler { 291*59813Shibler skip_args += 1; 292*59813Shibler inhibit_window_system = 1; 293*59813Shibler } 294*59813Shibler 295*59813Shibler /* Handle the -batch switch, which means don't do interactive display. */ 296*59813Shibler noninteractive = 0; 297*59813Shibler if (skip_args + 1 < argc && !strcmp (argv[skip_args + 1], "-batch")) 298*59813Shibler { 299*59813Shibler skip_args += 1; 300*59813Shibler noninteractive = 1; 301*59813Shibler } 302*59813Shibler 303*59813Shibler if ( 304*59813Shibler #ifndef CANNOT_DUMP 305*59813Shibler ! noninteractive || initialized 306*59813Shibler #else 307*59813Shibler 1 308*59813Shibler #endif 309*59813Shibler ) 310*59813Shibler { 311*59813Shibler /* Don't catch these signals in batch mode if not initialized. 312*59813Shibler On some machines, this sets static data that would make 313*59813Shibler signal fail to work right when the dumped Emacs is run. */ 314*59813Shibler signal (SIGHUP, fatal_error_signal); 315*59813Shibler signal (SIGQUIT, fatal_error_signal); 316*59813Shibler signal (SIGILL, fatal_error_signal); 317*59813Shibler signal (SIGTRAP, fatal_error_signal); 318*59813Shibler signal (SIGIOT, fatal_error_signal); 319*59813Shibler #ifdef SIGEMT 320*59813Shibler signal (SIGEMT, fatal_error_signal); 321*59813Shibler #endif 322*59813Shibler signal (SIGFPE, fatal_error_signal); 323*59813Shibler signal (SIGBUS, fatal_error_signal); 324*59813Shibler signal (SIGSEGV, fatal_error_signal); 325*59813Shibler signal (SIGSYS, fatal_error_signal); 326*59813Shibler signal (SIGTERM, fatal_error_signal); 327*59813Shibler #ifdef SIGXCPU 328*59813Shibler signal (SIGXCPU, fatal_error_signal); 329*59813Shibler #endif 330*59813Shibler #ifdef SIGXFSZ 331*59813Shibler signal (SIGXFSZ, fatal_error_signal); 332*59813Shibler #endif SIGXFSZ 333*59813Shibler 334*59813Shibler #ifdef AIX 335*59813Shibler signal (SIGDANGER, fatal_error_signal); 336*59813Shibler signal (20, fatal_error_signal); 337*59813Shibler signal (21, fatal_error_signal); 338*59813Shibler signal (22, fatal_error_signal); 339*59813Shibler signal (23, fatal_error_signal); 340*59813Shibler signal (24, fatal_error_signal); 341*59813Shibler signal (SIGAIO, fatal_error_signal); 342*59813Shibler signal (SIGPTY, fatal_error_signal); 343*59813Shibler signal (SIGIOINT, fatal_error_signal); 344*59813Shibler signal (SIGGRANT, fatal_error_signal); 345*59813Shibler signal (SIGRETRACT, fatal_error_signal); 346*59813Shibler signal (SIGSOUND, fatal_error_signal); 347*59813Shibler signal (SIGMSG, fatal_error_signal); 348*59813Shibler #endif /* AIX */ 349*59813Shibler } 350*59813Shibler 351*59813Shibler noninteractive1 = noninteractive; 352*59813Shibler 353*59813Shibler /* Perform basic initializations (not merely interning symbols) */ 354*59813Shibler 355*59813Shibler if (!initialized) 356*59813Shibler { 357*59813Shibler init_alloc_once (); 358*59813Shibler init_obarray (); 359*59813Shibler init_eval_once (); 360*59813Shibler init_syntax_once (); /* Create standard syntax table. */ 361*59813Shibler /* Must be done before init_buffer */ 362*59813Shibler init_buffer_once (); /* Create buffer table and some buffers */ 363*59813Shibler init_minibuf_once (); /* Create list of minibuffers */ 364*59813Shibler /* Must precede init_window_once */ 365*59813Shibler init_window_once (); /* Init the window system */ 366*59813Shibler } 367*59813Shibler 368*59813Shibler init_alloc (); 369*59813Shibler #ifdef MAINTAIN_ENVIRONMENT 370*59813Shibler init_environ (); 371*59813Shibler #endif 372*59813Shibler init_eval (); 373*59813Shibler init_data (); 374*59813Shibler init_read (); 375*59813Shibler 376*59813Shibler init_cmdargs (argc, argv, skip_args); /* Create list Vcommand_line_args */ 377*59813Shibler init_buffer (); /* Init default directory of main buffer */ 378*59813Shibler if (!noninteractive) 379*59813Shibler { 380*59813Shibler #ifdef VMS 381*59813Shibler init_vms_input ();/* init_display calls get_screen_size, that needs this */ 382*59813Shibler #endif /* VMS */ 383*59813Shibler init_display (); /* Determine terminal type. init_sys_modes uses results */ 384*59813Shibler } 385*59813Shibler init_keyboard (); /* This too must precede init_sys_modes */ 386*59813Shibler init_callproc (); /* And this too. */ 387*59813Shibler init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.) */ 388*59813Shibler init_xdisp (); 389*59813Shibler init_macros (); 390*59813Shibler init_editfns (); 391*59813Shibler #ifdef VMS 392*59813Shibler init_vmsfns (); 393*59813Shibler #endif /* VMS */ 394*59813Shibler #ifdef subprocesses 395*59813Shibler init_process (); 396*59813Shibler #endif /* subprocesses */ 397*59813Shibler 398*59813Shibler /* Intern the names of all standard functions and variables; define standard keys */ 399*59813Shibler 400*59813Shibler if (!initialized) 401*59813Shibler { 402*59813Shibler /* The basic levels of Lisp must come first */ 403*59813Shibler /* And data must come first of all 404*59813Shibler for the sake of symbols like error-message */ 405*59813Shibler syms_of_data (); 406*59813Shibler syms_of_alloc (); 407*59813Shibler #ifdef MAINTAIN_ENVIRONMENT 408*59813Shibler syms_of_environ (); 409*59813Shibler #endif MAINTAIN_ENVIRONMENT 410*59813Shibler syms_of_read (); 411*59813Shibler syms_of_print (); 412*59813Shibler syms_of_eval (); 413*59813Shibler syms_of_fns (); 414*59813Shibler 415*59813Shibler syms_of_abbrev (); 416*59813Shibler syms_of_buffer (); 417*59813Shibler syms_of_bytecode (); 418*59813Shibler syms_of_callint (); 419*59813Shibler syms_of_casefiddle (); 420*59813Shibler syms_of_callproc (); 421*59813Shibler syms_of_cmds (); 422*59813Shibler #ifndef NO_DIR_LIBRARY 423*59813Shibler syms_of_dired (); 424*59813Shibler #endif /* not NO_DIR_LIBRARY */ 425*59813Shibler syms_of_display (); 426*59813Shibler syms_of_doc (); 427*59813Shibler syms_of_editfns (); 428*59813Shibler syms_of_emacs (); 429*59813Shibler syms_of_fileio (); 430*59813Shibler #ifdef CLASH_DETECTION 431*59813Shibler syms_of_filelock (); 432*59813Shibler #endif /* CLASH_DETECTION */ 433*59813Shibler syms_of_indent (); 434*59813Shibler syms_of_keyboard (); 435*59813Shibler syms_of_keymap (); 436*59813Shibler syms_of_macros (); 437*59813Shibler syms_of_marker (); 438*59813Shibler syms_of_minibuf (); 439*59813Shibler syms_of_mocklisp (); 440*59813Shibler #ifdef subprocesses 441*59813Shibler syms_of_process (); 442*59813Shibler #endif /* subprocesses */ 443*59813Shibler syms_of_search (); 444*59813Shibler syms_of_syntax (); 445*59813Shibler syms_of_undo (); 446*59813Shibler syms_of_window (); 447*59813Shibler syms_of_xdisp (); 448*59813Shibler #ifdef HAVE_X_WINDOWS 449*59813Shibler syms_of_xfns (); 450*59813Shibler #ifdef HAVE_X_MENU 451*59813Shibler syms_of_xmenu (); 452*59813Shibler #endif /* HAVE_X_MENU */ 453*59813Shibler #endif /* HAVE_X_WINDOWS */ 454*59813Shibler 455*59813Shibler #ifdef SYMS_SYSTEM 456*59813Shibler SYMS_SYSTEM; 457*59813Shibler #endif 458*59813Shibler 459*59813Shibler #ifdef SYMS_MACHINE 460*59813Shibler SYMS_MACHINE; 461*59813Shibler #endif 462*59813Shibler 463*59813Shibler keys_of_casefiddle (); 464*59813Shibler keys_of_cmds (); 465*59813Shibler keys_of_buffer (); 466*59813Shibler keys_of_keyboard (); 467*59813Shibler keys_of_keymap (); 468*59813Shibler keys_of_macros (); 469*59813Shibler keys_of_minibuf (); 470*59813Shibler keys_of_window (); 471*59813Shibler } 472*59813Shibler 473*59813Shibler if (!initialized) 474*59813Shibler { 475*59813Shibler /* Handle -l loadup-and-dump, args passed by Makefile. */ 476*59813Shibler if (argc > 2 + skip_args && !strcmp (argv[1 + skip_args], "-l")) 477*59813Shibler Vtop_level = Fcons (intern ("load"), 478*59813Shibler Fcons (build_string (argv[2 + skip_args]), Qnil)); 479*59813Shibler #ifdef CANNOT_DUMP 480*59813Shibler /* Unless next switch is -nl, load "loadup.el" first thing. */ 481*59813Shibler if (!(argc > 1 + skip_args && !strcmp (argv[1 + skip_args], "-nl"))) 482*59813Shibler Vtop_level = Fcons (intern ("load"), 483*59813Shibler Fcons (build_string ("loadup.el"), Qnil)); 484*59813Shibler #endif /* CANNOT_DUMP */ 485*59813Shibler } 486*59813Shibler 487*59813Shibler initialized = 1; 488*59813Shibler 489*59813Shibler /* Enter editor command loop. This never returns. */ 490*59813Shibler Frecursive_edit (); 491*59813Shibler /* NOTREACHED */ 492*59813Shibler } 493*59813Shibler 494*59813Shibler DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P", 495*59813Shibler "Exit the Emacs job and kill it. ARG means no query.\n\ 496*59813Shibler If emacs is running noninteractively and ARG is an integer,\n\ 497*59813Shibler return ARG as the exit program code.") 498*59813Shibler (arg) 499*59813Shibler Lisp_Object arg; 500*59813Shibler { 501*59813Shibler Lisp_Object answer; 502*59813Shibler int i; 503*59813Shibler struct gcpro gcpro1; 504*59813Shibler 505*59813Shibler GCPRO1 (arg); 506*59813Shibler 507*59813Shibler if (!NULL (Vkill_emacs_hook)) 508*59813Shibler call0 (Vkill_emacs_hook); 509*59813Shibler 510*59813Shibler if (feof (stdin)) 511*59813Shibler arg = Qt; 512*59813Shibler 513*59813Shibler #ifdef subprocesses 514*59813Shibler kill_buffer_processes (Qnil); 515*59813Shibler #endif /* subprocesses */ 516*59813Shibler 517*59813Shibler #ifdef VMS 518*59813Shibler kill_vms_processes (); 519*59813Shibler #endif /* VMS */ 520*59813Shibler 521*59813Shibler Fdo_auto_save (Qt); 522*59813Shibler 523*59813Shibler #ifdef CLASH_DETECTION 524*59813Shibler unlock_all_files (); 525*59813Shibler #endif /* CLASH_DETECTION */ 526*59813Shibler 527*59813Shibler fflush (stdout); 528*59813Shibler reset_sys_modes (); 529*59813Shibler UNGCPRO; 530*59813Shibler 531*59813Shibler /* Is it really necessary to do this deassign 532*59813Shibler when we are going to exit anyway? */ 533*59813Shibler /* #ifdef VMS 534*59813Shibler stop_vms_input (); 535*59813Shibler #endif */ 536*59813Shibler stuff_buffered_input (arg); 537*59813Shibler #ifdef SIGIO 538*59813Shibler /* There is a tendency for a SIGIO signal to arrive within exit, 539*59813Shibler and cause a SIGHUP because the input descriptor is already closed. */ 540*59813Shibler unrequest_sigio (); 541*59813Shibler signal (SIGIO, SIG_IGN); 542*59813Shibler #endif 543*59813Shibler exit ((XTYPE (arg) == Lisp_Int) ? XINT (arg) 544*59813Shibler #ifdef VMS 545*59813Shibler : 1 546*59813Shibler #else 547*59813Shibler : 0 548*59813Shibler #endif 549*59813Shibler ); 550*59813Shibler /* NOTREACHED */ 551*59813Shibler } 552*59813Shibler 553*59813Shibler #ifndef CANNOT_DUMP 554*59813Shibler /* Nothing like this can be implemented on an Apollo. 555*59813Shibler What a loss! */ 556*59813Shibler 557*59813Shibler #ifdef HAVE_SHM 558*59813Shibler 559*59813Shibler DEFUN ("dump-emacs-data", Fdump_emacs_data, Sdump_emacs_data, 1, 1, 0, 560*59813Shibler "Dump current state of Emacs into data file FILENAME.\n\ 561*59813Shibler This function exists on systems that use HAVE_SHM.") 562*59813Shibler (intoname) 563*59813Shibler Lisp_Object intoname; 564*59813Shibler { 565*59813Shibler extern int my_edata; 566*59813Shibler Lisp_Object tem; 567*59813Shibler extern void malloc_warning (); 568*59813Shibler 569*59813Shibler CHECK_STRING (intoname, 0); 570*59813Shibler intoname = Fexpand_file_name (intoname, Qnil); 571*59813Shibler 572*59813Shibler tem = Vpurify_flag; 573*59813Shibler Vpurify_flag = Qnil; 574*59813Shibler 575*59813Shibler fflush (stdout); 576*59813Shibler /* Tell malloc where start of impure now is */ 577*59813Shibler /* Also arrange for warnings when nearly out of space. */ 578*59813Shibler #ifndef SYSTEM_MALLOC 579*59813Shibler malloc_init (&my_edata, malloc_warning); 580*59813Shibler #endif 581*59813Shibler map_out_data (XSTRING (intoname)->data); 582*59813Shibler 583*59813Shibler Vpurify_flag = tem; 584*59813Shibler 585*59813Shibler return Qnil; 586*59813Shibler } 587*59813Shibler 588*59813Shibler #else /* not HAVE_SHM */ 589*59813Shibler 590*59813Shibler DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0, 591*59813Shibler "Dump current state of Emacs into executable file FILENAME.\n\ 592*59813Shibler Take symbols from SYMFILE (presumably the file you executed to run Emacs).") 593*59813Shibler (intoname, symname) 594*59813Shibler Lisp_Object intoname, symname; 595*59813Shibler { 596*59813Shibler extern int my_edata; 597*59813Shibler Lisp_Object tem; 598*59813Shibler extern void malloc_warning (); 599*59813Shibler 600*59813Shibler CHECK_STRING (intoname, 0); 601*59813Shibler intoname = Fexpand_file_name (intoname, Qnil); 602*59813Shibler if (!NULL (symname)) 603*59813Shibler { 604*59813Shibler CHECK_STRING (symname, 0); 605*59813Shibler if (XSTRING (symname)->size) 606*59813Shibler symname = Fexpand_file_name (symname, Qnil); 607*59813Shibler } 608*59813Shibler 609*59813Shibler tem = Vpurify_flag; 610*59813Shibler Vpurify_flag = Qnil; 611*59813Shibler 612*59813Shibler fflush (stdout); 613*59813Shibler #ifdef VMS 614*59813Shibler mapout_data (XSTRING (intoname)->data); 615*59813Shibler #else 616*59813Shibler /* Tell malloc where start of impure now is */ 617*59813Shibler /* Also arrange for warnings when nearly out of space. */ 618*59813Shibler #ifndef SYSTEM_MALLOC 619*59813Shibler malloc_init (&my_edata, malloc_warning); 620*59813Shibler #endif 621*59813Shibler unexec (XSTRING (intoname)->data, 622*59813Shibler !NULL (symname) ? XSTRING (symname)->data : 0, &my_edata, 0, 0); 623*59813Shibler #endif /* not VMS */ 624*59813Shibler 625*59813Shibler Vpurify_flag = tem; 626*59813Shibler 627*59813Shibler return Qnil; 628*59813Shibler } 629*59813Shibler 630*59813Shibler #endif /* not HAVE_SHM */ 631*59813Shibler 632*59813Shibler #endif /* not CANNOT_DUMP */ 633*59813Shibler 634*59813Shibler #ifdef VMS 635*59813Shibler #define SEPCHAR ',' 636*59813Shibler #else 637*59813Shibler #define SEPCHAR ':' 638*59813Shibler #endif 639*59813Shibler 640*59813Shibler Lisp_Object 641*59813Shibler decode_env_path (evarname, defalt) 642*59813Shibler char *evarname, *defalt; 643*59813Shibler { 644*59813Shibler register char *path, *p; 645*59813Shibler extern char *index (); 646*59813Shibler 647*59813Shibler Lisp_Object lpath; 648*59813Shibler 649*59813Shibler path = (char *) egetenv (evarname); 650*59813Shibler if (!path) 651*59813Shibler path = defalt; 652*59813Shibler lpath = Qnil; 653*59813Shibler while (1) 654*59813Shibler { 655*59813Shibler p = index (path, SEPCHAR); 656*59813Shibler if (!p) p = path + strlen (path); 657*59813Shibler lpath = Fcons (p - path ? make_string (path, p - path) : Qnil, 658*59813Shibler lpath); 659*59813Shibler if (*p) 660*59813Shibler path = p + 1; 661*59813Shibler else 662*59813Shibler break; 663*59813Shibler } 664*59813Shibler return Fnreverse (lpath); 665*59813Shibler } 666*59813Shibler 667*59813Shibler syms_of_emacs () 668*59813Shibler { 669*59813Shibler #ifndef CANNOT_DUMP 670*59813Shibler #ifdef HAVE_SHM 671*59813Shibler defsubr (&Sdump_emacs_data); 672*59813Shibler #else 673*59813Shibler defsubr (&Sdump_emacs); 674*59813Shibler #endif 675*59813Shibler #endif /* not CANNOT_DUMP */ 676*59813Shibler 677*59813Shibler defsubr (&Skill_emacs); 678*59813Shibler 679*59813Shibler DEFVAR_LISP ("command-line-args", &Vcommand_line_args, 680*59813Shibler "Args passed by shell to Emacs, as a list of strings."); 681*59813Shibler 682*59813Shibler DEFVAR_LISP ("system-type", &Vsystem_type, 683*59813Shibler "Symbol indicating type of operating system you are using."); 684*59813Shibler Vsystem_type = intern (SYSTEM_TYPE); 685*59813Shibler 686*59813Shibler DEFVAR_BOOL ("noninteractive", &noninteractive1, 687*59813Shibler "Non-nil means Emacs is running without interactive terminal."); 688*59813Shibler 689*59813Shibler Vkill_emacs_hook = Qnil; 690*59813Shibler 691*59813Shibler DEFVAR_LISP ("kill-emacs-hook", &Vkill_emacs_hook, 692*59813Shibler "Function called, if non-nil, whenever kill-emacs is called."); 693*59813Shibler } 694