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