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