Annotation of 43BSD/contrib/emacs/src/emacs.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.