|
|
1.1 ! root 1: /* Fully extensible Emacs, running on Unix, intended for GNU. ! 2: Copyright (C) 1985 Richard M. Stallman. ! 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: ! 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 USG5 ! 34: #include <fcntl.h> ! 35: #endif ! 36: ! 37: #ifdef BSD ! 38: #include <sys/ioctl.h> ! 39: #endif ! 40: ! 41: #ifndef O_RDWR ! 42: #define O_RDWR 2 ! 43: #endif ! 44: ! 45: #define PRIO_PROCESS 0 ! 46: ! 47: /* Command line args from shell, as list of strings */ ! 48: Lisp_Object Vcommand_line_args; ! 49: ! 50: /* Set nonzero after Emacs has started up the first time. ! 51: Prevents reinitialization of the Lisp world and keymaps ! 52: on subsequent starts. */ ! 53: int initialized; ! 54: ! 55: /* Variable whose value is symbol giving operating system type */ ! 56: Lisp_Object Vsystem_type; ! 57: ! 58: /* Nonzero means running Emacs without interactive terminal. */ ! 59: ! 60: int noninteractive; ! 61: ! 62: /* Value of Lisp variable `noninteractive'. ! 63: Normally same as C variable `noninteractive' ! 64: but nothing terrible happens if user sets this one. */ ! 65: ! 66: int noninteractive1; ! 67: ! 68: /* Signal code for the fatal signal that was received */ ! 69: int fatal_error_code; ! 70: ! 71: /* Nonzero if handling a fatal error already */ ! 72: int fatal_error_in_progress; ! 73: ! 74: /* Handle bus errors, illegal instruction, etc. */ ! 75: fatal_error_signal (sig) ! 76: int sig; ! 77: { ! 78: #ifdef BSD ! 79: int tpgrp; ! 80: #endif /* BSD */ ! 81: ! 82: fatal_error_code = sig; ! 83: signal (sig, SIG_DFL); ! 84: ! 85: /* If fatal error occurs in code below, avoid infinite recursion. */ ! 86: if (fatal_error_in_progress) ! 87: kill (getpid (), fatal_error_code); ! 88: ! 89: fatal_error_in_progress = 1; ! 90: ! 91: /* If we are controlling the terminal, reset terminal modes */ ! 92: #ifdef BSD ! 93: if (ioctl(0, TIOCGPGRP, &tpgrp) == 0 ! 94: && tpgrp == getpgrp (0)) ! 95: #endif /* BSD */ ! 96: { ! 97: reset_sys_modes (); ! 98: if (sig != SIGTERM) ! 99: fprintf (stderr, "Fatal error."); ! 100: } ! 101: ! 102: /* Clean up */ ! 103: #ifdef subprocesses ! 104: kill_buffer_processes (Qnil); ! 105: #endif ! 106: Fdo_auto_save (Qt); ! 107: ! 108: #ifdef CLASH_DETECTION ! 109: unlock_all_files (); ! 110: #endif /* CLASH_DETECTION */ ! 111: ! 112: /* Signal the same code; this time it will really be fatal. */ ! 113: kill (getpid (), fatal_error_code); ! 114: } ! 115: ! 116: /* Code for dealing with Lisp access to the Unix command line */ ! 117: ! 118: static ! 119: init_cmdargs (argc, argv, skip_args) ! 120: int argc; ! 121: char **argv; ! 122: int skip_args; ! 123: { ! 124: register int i; ! 125: ! 126: Vcommand_line_args = Qnil; ! 127: ! 128: for (i = argc - 1; i >= 0; i--) ! 129: { ! 130: if (i == 0 || i > skip_args) ! 131: Vcommand_line_args ! 132: = Fcons (build_string (argv[i]), Vcommand_line_args); ! 133: } ! 134: } ! 135: ! 136: /* ARGSUSED */ ! 137: main (argc, argv, envp) ! 138: int argc; ! 139: char **argv; ! 140: char **envp; ! 141: { ! 142: int skip_args = 0; ! 143: extern int errno; ! 144: clearerr (stdin); ! 145: ! 146: #ifdef APOLLO /* Reserve memory space for sbrk to get */ ! 147: set_sbrk_size (4000000); ! 148: #endif /* APOLLO */ ! 149: ! 150: signal (SIGHUP, fatal_error_signal); ! 151: signal (SIGQUIT, fatal_error_signal); ! 152: signal (SIGILL, fatal_error_signal); ! 153: signal (SIGTRAP, fatal_error_signal); ! 154: signal (SIGIOT, fatal_error_signal); ! 155: signal (SIGEMT, fatal_error_signal); ! 156: signal (SIGFPE, fatal_error_signal); ! 157: signal (SIGBUS, fatal_error_signal); ! 158: signal (SIGSEGV, fatal_error_signal); ! 159: signal (SIGSYS, fatal_error_signal); ! 160: signal (SIGTERM, fatal_error_signal); ! 161: #ifdef SIGXCPU ! 162: signal (SIGXCPU, fatal_error_signal); ! 163: #endif ! 164: #ifdef SIGXFSZ ! 165: signal (SIGXFSZ, fatal_error_signal); ! 166: #endif SIGXFSZ ! 167: ! 168: #ifdef HIGHPRI ! 169: setpriority(PRIO_PROCESS, getpid(), HIGHPRI); ! 170: setuid(getuid()); ! 171: #endif HIGHPRI ! 172: ! 173: /* Handle the -t switch, which specifies filename to use as terminal */ ! 174: if (2 < argc && !strcmp (argv[1], "-t")) ! 175: { ! 176: skip_args = 2; ! 177: close (0); ! 178: close (1); ! 179: open(argv[2], O_RDWR, 2 ); ! 180: dup (0); ! 181: fprintf (stderr, "Using %s\n", argv[2]); ! 182: } ! 183: ! 184: /* Handle the -batch switch, which means don't do interactive display. */ ! 185: noninteractive = 0; ! 186: if (1 < argc && !strcmp (argv[1], "-batch")) ! 187: { ! 188: skip_args = 1; ! 189: noninteractive = 1; ! 190: } ! 191: ! 192: noninteractive1 = noninteractive; ! 193: ! 194: /* Perform basic initializations (not merely interning symbols) */ ! 195: ! 196: if (!initialized) ! 197: { ! 198: init_alloc_once (); ! 199: init_obarray (); ! 200: init_eval_once (); ! 201: init_syntax_once (); /* Create standard syntax table. */ ! 202: /* Must be done before init_buffer */ ! 203: init_buffer_once (); /* Create buffer table and some buffers */ ! 204: init_minibuf_once (); /* Create list of minibuffers */ ! 205: /* Must precede init_window_once */ ! 206: init_window_once (); /* Init the window system */ ! 207: } ! 208: ! 209: init_alloc (); ! 210: init_eval (); ! 211: init_data (); ! 212: init_read (); ! 213: ! 214: init_cmdargs (argc, argv, skip_args); /* Create list Vcommand_line_args */ ! 215: init_buffer (); /* Init default directory of main buffer */ ! 216: if (!noninteractive) ! 217: init_display (); /* Determine terminal type. init_sys_modes uses results */ ! 218: init_keyboard (); /* This too must precede init_sys_modes */ ! 219: init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.) */ ! 220: init_xdisp (); ! 221: init_macros (); ! 222: init_editfns (); ! 223: init_callproc (); ! 224: #ifdef subprocesses ! 225: init_process (); ! 226: #endif subprocesses ! 227: ! 228: /* Intern the names of all standard functions and variables; define standard keys */ ! 229: ! 230: if (!initialized) ! 231: { ! 232: /* The basic levels of Lisp must come first */ ! 233: /* And data must come first of all ! 234: for the sake of symbols like error-message */ ! 235: syms_of_data (); ! 236: syms_of_alloc (); ! 237: syms_of_read (); ! 238: syms_of_print (); ! 239: syms_of_eval (); ! 240: syms_of_fns (); ! 241: ! 242: syms_of_abbrev (); ! 243: syms_of_buffer (); ! 244: syms_of_bytecode (); ! 245: syms_of_callint (); ! 246: syms_of_casefiddle (); ! 247: syms_of_callproc (); ! 248: syms_of_cmds (); ! 249: #ifndef NO_DIR_LIBRARY ! 250: syms_of_dired (); ! 251: #endif /* not NO_DIR_LIBRARY */ ! 252: syms_of_display (); ! 253: syms_of_doc (); ! 254: syms_of_editfns (); ! 255: syms_of_emacs (); ! 256: syms_of_fileio (); ! 257: #ifdef CLASH_DETECTION ! 258: syms_of_filelock (); ! 259: #endif /* CLASH_DETECTION */ ! 260: syms_of_indent (); ! 261: syms_of_keyboard (); ! 262: syms_of_keymap (); ! 263: syms_of_macros (); ! 264: syms_of_marker (); ! 265: syms_of_minibuf (); ! 266: syms_of_mocklisp (); ! 267: #ifdef subprocesses ! 268: syms_of_process (); ! 269: #endif /* subprocesses */ ! 270: syms_of_search (); ! 271: syms_of_syntax (); ! 272: syms_of_undo (); ! 273: syms_of_window (); ! 274: syms_of_xdisp (); ! 275: #ifdef HAVE_X_WINDOWS ! 276: syms_of_xfns (); ! 277: #endif /* HAVE_X_WINDOWS */ ! 278: ! 279: keys_of_casefiddle (); ! 280: keys_of_cmds (); ! 281: keys_of_buffer (); ! 282: keys_of_keyboard (); ! 283: keys_of_keymap (); ! 284: keys_of_macros (); ! 285: keys_of_minibuf (); ! 286: keys_of_window (); ! 287: } ! 288: ! 289: if (!initialized) ! 290: { ! 291: /* Handle -l loadup-and-dump, args passed by Makefile. */ ! 292: if (argc > 2 + skip_args && !strcmp (argv[1 + skip_args], "-l")) ! 293: Vtop_level = Fcons (intern ("load"), ! 294: Fcons (build_string (argv[2 + skip_args]), Qnil)); ! 295: #ifdef CANNOT_DUMP ! 296: /* Unless next switch is -nl, load "loadup.el" first thing. */ ! 297: if (!(argc > 1 + skip_args && !strcmp (argv[1 + skip_args], "-nl"))) ! 298: Vtop_level = Fcons (intern ("load"), ! 299: Fcons (build_string ("loadup.el"), Qnil)); ! 300: #endif /* CANNOT_DUMP */ ! 301: } ! 302: ! 303: initialized = 1; ! 304: ! 305: /* Enter editor command loop. This never returns. */ ! 306: Frecursive_edit (); ! 307: /* NOTREACHED */ ! 308: } ! 309: ! 310: DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P", ! 311: "Exit the Emacs job and kill it. ARG means no query.\n\ ! 312: If emacs is running noninteractively and ARG is an integer,\n\ ! 313: return ARG as the exit program code.") ! 314: (arg) ! 315: Lisp_Object arg; ! 316: { ! 317: Lisp_Object answer; ! 318: int i; ! 319: ! 320: if (feof (stdin)) ! 321: arg = Qt; ! 322: if (!noninteractive && NULL (arg)) ! 323: { ! 324: if ((i = ModExist()) ! 325: && (answer = Fyes_or_no_p (format1 ( ! 326: "%d modified buffer%s exist%s, do you really want to exit? ", ! 327: i, i == 1 ? "" : "s", ! 328: i == 1 ? "s" : "")), ! 329: NULL (answer))) ! 330: return Qnil; ! 331: ! 332: #ifdef subprocesses ! 333: if (count_active_processes() ! 334: && (answer = Fyes_or_no_p (format1 ( ! 335: "Subprocesses are executing; kill them and exit? ")), ! 336: NULL (answer))) ! 337: return Qnil; ! 338: #endif /* subprocesses */ ! 339: } ! 340: ! 341: #ifdef subprocesses ! 342: kill_buffer_processes (Qnil); ! 343: #endif /* subprocesses */ ! 344: ! 345: Fdo_auto_save (Qt); ! 346: ! 347: #ifdef CLASH_DETECTION ! 348: unlock_all_files (); ! 349: #endif /* CLASH_DETECTION */ ! 350: ! 351: fflush (stdout); ! 352: reset_sys_modes (); ! 353: stuff_buffered_input (arg); ! 354: exit ((XTYPE (arg) == Lisp_Int) ? XINT (arg) : 0); ! 355: /* NOTREACHED */ ! 356: } ! 357: ! 358: #ifndef CANNOT_DUMP ! 359: /* Nothing like this can be implemented on an Apollo. ! 360: What a loss! */ ! 361: ! 362: DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0, ! 363: "Dump current state of Emacs into executable file FILENAME.\n\ ! 364: Take symbols from SYMFILE (presumably the file you executed to run Emacs).") ! 365: (intoname, symname) ! 366: Lisp_Object intoname, symname; ! 367: { ! 368: register unsigned char *a_name = 0; ! 369: extern int my_edata; ! 370: Lisp_Object tem; ! 371: extern _start (); ! 372: ! 373: CHECK_STRING (intoname, 0); ! 374: intoname = Fexpand_file_name (intoname, Qnil); ! 375: if (!NULL (symname)) ! 376: { ! 377: CHECK_STRING (symname, 0); ! 378: if (XSTRING (symname)->size) ! 379: { ! 380: symname = Fexpand_file_name (symname, Qnil); ! 381: a_name = XSTRING (symname)->data; ! 382: } ! 383: } ! 384: ! 385: tem = Vpurify_flag; ! 386: Vpurify_flag = Qnil; ! 387: ! 388: fflush (stdout); ! 389: malloc_init (&my_edata); /* Tell malloc where start of impure now is */ ! 390: unexec (XSTRING (intoname)->data, a_name, &my_edata, 0, _start); ! 391: ! 392: Vpurify_flag = tem; ! 393: ! 394: return Qnil; ! 395: } ! 396: ! 397: #endif /* not CANNOT_DUMP */ ! 398: ! 399: Lisp_Object ! 400: decode_env_path (evarname, defalt) ! 401: char *evarname, *defalt; ! 402: { ! 403: register char *path, *p; ! 404: extern char *index (); ! 405: ! 406: Lisp_Object lpath; ! 407: ! 408: path = (char *) getenv (evarname); ! 409: if (!path) ! 410: path = defalt; ! 411: lpath = Qnil; ! 412: while (1) ! 413: { ! 414: p = index (path, ':'); ! 415: if (!p) p = path + strlen (path); ! 416: lpath = Fcons (p - path ? make_string (path, p - path) : Qnil, ! 417: lpath); ! 418: if (*p) ! 419: path = p + 1; ! 420: else ! 421: break; ! 422: } ! 423: return Fnreverse (lpath); ! 424: } ! 425: ! 426: syms_of_emacs () ! 427: { ! 428: #ifndef CANNOT_DUMP ! 429: defsubr (&Sdump_emacs); ! 430: #endif /* not CANNOT_DUMP */ ! 431: ! 432: defsubr (&Skill_emacs); ! 433: ! 434: DefLispVar ("command-line-args", &Vcommand_line_args, ! 435: "Args passed by shell to Emacs, as a list of strings."); ! 436: ! 437: DefLispVar ("system-type", &Vsystem_type, ! 438: "Symbol indicating type of operating system you are using."); ! 439: Vsystem_type = intern (SYSTEM_TYPE); ! 440: ! 441: DefBoolVar ("noninteractive", &noninteractive1, ! 442: "Non-nil means Emacs is running without interactive terminal."); ! 443: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.