Annotation of researchv9/X11/src/X.V11R1/clients/emacs/emacs.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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