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