/************************************************************************ * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is * * provided to you without charge, and with no warranty. You may give * * away copies of JOVE, including sources, provided that this notice is * * included in all the files. * ************************************************************************/ /* Contains the main loop initializations. [TRH] moved the system dependent things to new file "tty.c" since this file was getting too big for my compiler (yes I should get a better compiler:-). */ #define NO_PROCDECL /* kludge for teensy pdp11 compiler */ #define Extern #include "jove.h" RCS("$Id: jove.c,v 14.32.0.12 1994/06/24 17:55:02 tom Exp tom $") #include "ctype.h" #include "io.h" #include "process.h" #ifndef NO_PROCDECL #include "rec.h" #include "screen.h" #else # ifdef TERMCAP # undef TERMCAP # define TERMCAP -1 /* throw out most declarations from termcap.h */ # endif #endif #include "termcap.h" #ifndef RESHAPING # undef SIGWINCH /* To simplify conditional code. */ #endif time_t time0; /* when jove started up */ time_t now; /* (about) now; updated by updmode(). */ int errormsg ZERO; const char NullStr[1] ZERO; /* Handle signals, or exit regulaurly if `code' is zero. */ sig_tp finish(code) register int code; { static int Crashing ZERO, KeepTmps ZERO; /* Usually we delete them. */ #ifdef LSRHS if (code != 0 && code != SIGHUP) setdump(1); #endif #if unix || vms # ifdef TERMIOS if (code == SIGQUIT) code = SIGINT; # endif if (code == SIGINT) { char c; # ifndef kbd register int state = kbd(OFF); # endif # ifdef RESIGNAL signal(code, finish); # endif f_mess("A)bort or I)nterrupt ? "); read_one_char(&c); message(NullStr); # ifndef kbd kbd(state); # endif switch (toupper(c)) { case 'A': case 'Y': /* for old habits' sake */ break; case 'I': error((char *)0); default: redisplay(); return; } } #endif #ifdef IPROCS # ifdef SIGCHLD signal(SIGCHLD, SIG_DFL); # endif KillProcs(); # ifdef PIPEPROCS kbd_kill(); # endif #endif #ifdef VARTERM set_tdim(0, 0); # ifdef SIGWINCH signal(SIGWINCH, SIG_DFL); # endif ttsize(); /* to let system restore default size. */ #endif UnsetTerm((char *)0); if (code != 0) { if (!Crashing++) { /*- lsave(); -*/ /* SyncRec() now lsave()s */ SyncRec(); printf("\7%s\nJOVE CRASH!! (code %d)\n", mesgbuf, code); if (ModBufs(1)) { KeepTmps++; /* Don't delete anymore. */ printf("\ Your buffers have been saved.\n\ Use \"jove_recover\" or \"jove -r\"\n\ to have a look at them.\n"); } else printf("You didn't lose any work.\n"); } else printf("\r\nYou may have lost your work!\n"); } if (!KeepTmps) { tmpclose(); recclose(); } #if !unix ttexit(); #endif flusho(); if (code != 0) { #if unix || vms if (code > 0) { /* Re-send ourselves the signal to die as we should. */ signal(code, SIG_DFL); kill(getpid(), code); # ifdef HOLD_SIGS sigrelse(code); # endif } #else /* !(unix || vms) */ if ( # ifdef SIGHUP code != SIGHUP || # endif code != SIGTERM) #endif /* (unix || vms) */ abort(); } #ifdef PROFILING exit(EXIT_SUCCESS); #else _exit(EXIT_SUCCESS); #endif } /* Handle window change signal. */ #ifdef SIGWINCH private int winch_pending ZERO; private sig_tp winch __(( int _(sig) )); private sig_tp winch(sig) { # ifdef RESIGNAL signal(sig, winch); # endif /* Since `win_reshape' reallocates, and `malloc' is generally non-reentrant, so defer reshaping if we're not reading input. {{TODO: sync with process input handling.}} Also avoid reshaping if we get a nested SIGWINCH (this cannot happen anyway on BSD/Posix-style signalled systems where the signal is blocked while it is handled.) */ if (!winch_pending++) { if (inIOread) { win_reshape(); winch_pending = NO; } } } #endif #if __POSIX__ /* Strict Posix does NOT support signal(), so we have to emulate it. */ sig_tp (*signal(sig, handler))() int sig; sig_tp (*handler)__(( int )); { struct sigaction s, o; s.sa_handler = handler; sigemptyset(&s.sa_mask); s.sa_flags = 0; if(sigaction(sig, &s, &o) < 0) return SIG_ERR; return o.sa_handler; } #endif /* __POSIX__ */ #if unix || vms /* A common set of signals */ Signal SigIntQuit[] = { SIGINT, SIG_IGN, SIGQUIT, SIG_IGN }; /* set a bunch of signals */ void SetSigs(sigs, num) register const Signal *sigs; register int num; { do { signal(sigs->sig, sigs->proc); sigs++; } while (--num); } /* set a bunch of signals to SIG_IGN, storing their original values */ void GetSigs(sigs, num) register Signal *sigs; register int num; { do { sigs->proc = signal(sigs->sig, SIG_IGN); sigs++; } while (--num); } #endif /* unix || vms */ #ifndef NOPROCS DEF_STR( "i-shell", IShell, 40, V_FILENAME ) _IF(ndef NOPROCS) ZERO; DEF_STR( "i-shell-flags", IShFlags, 16, V_STRING ) _IF(ndef NOPROCS) = "-i"; #endif #if unix # ifdef JOB_CONTROL DEF_CMD( "pause-jove", PauseJove, NO ); _IF(def JOB_CONTROL) DEF_CMD( "suspend-jove", PauseJove, NO ) _IF(def JOB_CONTROL) { #ifdef IPROCS # ifdef PIPEPROCS register int state = kbd(OFF); # else sighold(SIGCHLD); # endif #endif SyncRec(); /* just in case we decide to logout... */ UnsetTerm(ModBufs(0) ? "[There are modified buffers]" : (char *)0); kill(0, SIGTSTP); ResetTerm(); ClAndRedraw(); #ifdef RESHAPING /* * We don't seem to get any SIGWINCH signals while we're stopped, * (since we're taken off the current terminal's process group?), * so explicitly check for any window size changes. */ win_reshape(); #endif #ifdef IPROCS # ifdef PIPEPROCS kbd(state); # else sigrelse(SIGCHLD); # endif #endif } # endif DEF_CMD( "pause-jove", Push, NO ); _IF(ndef NOPROCS)_IF(ndef JOB_CONTROL)_IF(!vms) DEF_CMD( "push-shell", Push, NO ) _IF(ndef NOPROCS) { register const char *shell; register int pid; #ifdef IPROCS # ifdef PIPEPROCS register int state = kbd(OFF); # else sighold(SIGCHLD); # endif #endif #ifdef SIGWINCH # ifdef HOLD_SIGS sighold(SIGWINCH); # else signal(SIGWINCH, SIG_DFL); # endif #endif if ((shell = IShell) == NULL) shell = Shell; GetSigs(SigIntQuit, sizeof SigIntQuit / sizeof SigIntQuit[0]); if ((pid = vfork()) <= 0) { static const Signal sigs[] = { SIGTERM, SIG_DFL, SIGINT, SIG_DFL, SIGQUIT, SIG_DFL }; #ifdef IPROCS /* Necessary??? */ # ifndef PIPEPROCS sigrelse(SIGCHLD); # endif #endif #ifdef SIGWINCH /* Necessary??? */ # ifdef HOLD_SIGS sigrelse(SIGWINCH); # endif #endif if (pid < 0) #ifdef IPROCS # ifdef PIPEPROCS kbd(state), # endif #endif complain("[Fork failed]"); UnsetTerm(ModBufs(0) ? "[There are modified buffers]" : (char *)0); SetSigs(sigs, sizeof sigs / sizeof sigs[0]); execl(shell, basename(shell), IShFlags, (char *)0); exec_fail(Shell); } dowait(pid); #ifdef IPROCS # ifdef PIPEPROCS kbd(state); # else sigrelse(SIGCHLD); # endif #endif #ifdef SIGWINCH # ifdef HOLD_SIGS sigrelse(SIGWINCH); # else signal(SIGWINCH, winch); # endif #endif ResetTerm(); ClAndRedraw(); SetSigs(SigIntQuit, sizeof SigIntQuit / sizeof SigIntQuit[0]); } #endif /* unix */ int this_cmd, last_cmd; int LastKeyStruck; DEF_INT( "meta-key", MetaKey, V_CHAR|V_TTY_RESET ) ZERO; int InputPending ZERO; char *Inputp ZERO; private int peekbuf[10], *peekp = peekbuf; #define IsPeekc() (peekp > peekbuf) #define GetPeekc() (*--peekp) Peekc() { return (IsPeekc() ? GetPeekc() : -1); } void Ungetc(c) { if (peekp == &peekbuf[(sizeof peekbuf) - 1]) return; /* Sorry, can't oblige you ... */ *peekp++ = c; } int getch() { register int c; extern int ModCount; /* * Are there any ungetc'd chars? * [TRH] moved this in front to facilitate handling of * 8-bit characters from .joverc. (use the macros for efficiency) */ if (IsPeekc()) return LastKeyStruck = GetPeekc(); /* * string input? (e.g. from .joverc) */ if (Inputp) { if ((c = *Inputp) != 0) { Inputp++; #if (BPC == 8) if (c & 0200) { /* prepend 8-bit char with QuoteChar. */ Ungetc(c); return LastKeyStruck = QuoteChar; } #endif return LastKeyStruck = _UC_(c); } Inputp = NULL; if (InJoverc) /* implied newline in .joverc */ return LastKeyStruck = '\n'; } if (InJoverc) return EOF; /* somethings wrong if Inputp runs out while we're reading a .joverc file. */ if (ModCount >= SyncFreq && SyncFreq) { ModCount = 0; SyncRec(); } /* * If we're not interactive and we're not executing a macro, * we read from the terminal (i.e., getchar()). * And characters only get put in macros from inside this if. */ if (Interactive || ((c = mac_getc()) < 0)) { /* * So messages that aren't error messages don't * hang around forever. Don't erase if we are asking. */ if (mesgbuf[0] && !UpdMesg && !Asking && !errormsg) message(NullStr); redisplay(); inIOread = YES; #ifdef SIGWINCH /* * Handle a pending window change. */ if (winch_pending) { win_reshape(); winch_pending = NO; } #endif c = getchar(); inIOread = NO; #if (HIGHLIGHT) WUnHighLight(curwind); #endif if (Defining && !Interactive) mac_putc(c); } add_stroke(c); return LastKeyStruck = c; } #ifndef INT_MAX # define INT_MAX ((int)((1<<(sizeof(int)*8-1)) - 1)) #endif #ifndef NOPROCS /* [TRH 4/89] this is setup by main when JOVE is used in a pipe. */ private int pipe_fd ZERO; #endif #ifdef F_COMPLETION # ifndef TINY DEF_INT( "ignore-bad-file-args", IgnBadFiles, V_BOOL) _IF(def F_COMPLETION)_IF(ndef TINY) ZERO; # endif #endif private void do_cmdline __(( int _(argc), char *_(argv)[] )); private void do_cmdline(argc, argv) int argc; register char *argv[]; { register char *arg; register int nwinds = 1, lineno = 0, plus, view_mode = 0; register Buffer *b; #ifdef CLIOPTIONS int i; #endif #ifndef NOPROCS if (pipe_fd > 0) { /* read piped input in Mainbuf */ read_pipe(Mainbuf, pipe_fd, YES); nwinds--; } #endif ShowVersion(); argv++; while (--argc > 0) { arg = *argv++; /* [TRH] treat -x as default, +x as special (tags and errors) */ if (!(plus = (*arg == '+')) && !(*arg == '-')) { #ifdef ARG_EXPAND for (; arg = arg_expand(arg) ; arg = NULL) #endif { #if vms char *vms2ux __(( char *_(buf), const char *_(src) )); char tmp[FILESIZE]; arg = vms2ux(tmp, arg); #else FIX_FILENAME(arg); #endif #ifdef F_COMPLETION # ifndef TINY if (True(IgnBadFiles) && (bad_extension(arg) || isdir(arg))) continue; # endif #endif minib_add(arg, nwinds|lineno); b = do_find(nwinds ? curwind : (Window *)0, arg, lineno); lineno = 0; if (nwinds) { SetABuf(curbuf); SetBuf(b); if (--nwinds) NextWindow(); } if (view_mode) { b->b_minor |= View; view_mode--; } } #ifdef CLIOPTIONS } else if ((i = CliLookup(arg, argc, argv)) >= 0) { argc -= i; argv += i; #endif } else switch (++arg, *arg++) { case 'd': /* CWD handled in main() */ --argc; argv++; break; #ifndef CLIOPTIONS /* these options can be implemented using JOVEs "command-line-option" command */ case 'j': if (!plus) /* "-j" Ignore .joverc in HOME */ break; /* "+j " read rc file */ if (--argc == 0) break; if (!joverc(*argv++)) f_mess(IOerr("read", arg)); break; case 'p': if (--argc == 0) break; FIX_FILENAME(*argv); SetBuf(do_find(curwind, *argv++, 0)); exp_p = plus; ParseAll(); nwinds = 0; break; case 't': /* -t: default tagfile, +t: ask */ --argc; find_tag(*argv++, plus); break; #endif /* CLIOPTIONS */ case 'v': /* view mode, -v single +v all files */ view_mode = (plus) ? INT_MAX : 1; break; case 'w': if (*arg == '\0') plus = 1; else plus = chr_to_int(arg, 10, NIL) - 1; div_wind(curwind, plus); nwinds += plus; break; case '\0': /* '-': go to end of buffer */ lineno = INT_MAX; /* can't use -1 since that would position to EOF-1 */ break; default: if (isdigit(*--arg)) { /* +N: go to line N */ /* -N: go to line (EOF - N) */ lineno = chr_to_int(arg, 10, 0); if (!plus) lineno = -lineno; } else { rbell(); message(NullStr); PutErrInBuf("*CLI errors*", --arg, 0, "[Unknown option]"); } break; } } #ifdef CLIOPTIONS CliDelete(); #endif if (lineno) to_line(lineno); } private void do_err __(( int _(error), const char *_(fmt), va_list _(ap) )); private void do_err(error, fmt, ap) const char *fmt; va_list ap; { register const char *f; if (f = fmt) { format(mesgbuf, sizeof mesgbuf, f, ap); updmesg(); } va_end(ap); rbell(); jump_env(error); } /* VARARGS1 */ void DEFVARG(error, (const char *fmt, ...), (fmt, va_alist) const char *fmt;) { va_register va_list ap; va_begin(ap, fmt); do_err(ERROR, fmt, ap); } /* VARARGS1 */ void DEFVARG(complain, (const char *fmt, ...), (fmt, va_alist) const char *fmt;) { va_register va_list ap; va_begin(ap, fmt); do_err(COMPLAIN, fmt, ap); } /* VARARGS1 */ void DEFVARG(confirm, (const char *fmt, ...), (fmt, va_alist) const char *fmt;) { va_register va_list ap; VA_INIT_PROPAGATE rbell(); va_begin(ap, fmt); if (yes_or_no_p('N', VA_PROPAGATE(fmt, ap)) == NO) { va_end(ap); jump_env(COMPLAIN); } va_end(ap); } private void check_mods __(( void )); private void check_mods() { register const char *leave_anyway = "Some %s haven't been saved; leave anyway? "; if (ModMacs()) confirm(leave_anyway, "MACROS"); if (ModBufs(0)) confirm(leave_anyway, "buffers"); } DEF_CMD( "quick-exit", QuickExit, NO ) { put_bufs((exp_p & YES), YES); /* Kludge. Avoid update of mode line (that clobbers the file name list) when asking to leave or to kill i-processes. */ UpdModLine = NO; check_mods(); finish(0); } DEF_CMD( "exit-jove", Leave, NO ) { jump_env(QUIT); } private jmp_buf first_env; jmp_buf *mainjmp = &first_env; private int iniargc; /* main sets these for DoKeys() */ private char **iniargv; private void DoKeys __(( void )); private void DoKeys() { register int c; Savejmp savejmp; switch (push_env(savejmp)) { case 0: if (c = iniargc) { iniargc = 0; do_cmdline(c, iniargv); } break; case QUIT: if (RecDepth == 0) check_mods(); pop_env(savejmp); return; case ERROR: getDOT(); /* God knows what state linebuf was in */ case COMPLAIN: gc_openfiles(); /* close any files we left open */ fix_macros(); errormsg++; Asking = 0; if (!in_macro()) { /* don't redisplay if we catch error */ curwind->w_bufp = curbuf; redisplay(); } break; } this_cmd = last_cmd = 0; for (;;) { if (this_cmd != ARG_CMD) { exp = 1; exp_p = NO; last_cmd = this_cmd; init_strokes(); } if ((c = getch()) >= 0) dispatch(c); } } int RecDepth ZERO; DEF_CMD( "recursive-edit", Recur, NO ) { register Buffer *cb = curwind->w_bufp; register Mark *m; register char *bname; register int o_Interactive = Interactive; SetBuf(cb); /* if Asking, curbuf != curwind->w_bufp */ Asking = NO; bname = copystr(cb->b_name); m = MakeMark(cb->b_dot, cb->b_char, FLOATER); if (exp_p) Interactive++; /* Force interactive mode */ RecDepth++; updmodline(); DoKeys(); RecDepth--; updmodline(); Interactive = o_Interactive; if (!buf_exists(bname)) /* [TRH] if buffer is deleted, */ m = NULL; /* this mark is gone too... */ SetBuf(do_select(curwind, bname)); free(bname); if (m) { if (exp_p == NO) ToMark(m); DelMark(m); } } #ifndef ExecNow void ExecNow(cp) register const data_obj *cp; { if ((cp->Type & TYPEMASK) == MACRO) { /* Immediate macro execution need some attention. */ register int o_InJoverc = InJoverc; register char *o_Inputp = Inputp; char o_mesgbuf[sizeof mesgbuf]; strcpy(o_mesgbuf, mesgbuf); InJoverc = 0; Inputp = NULL; ((Macro *) cp)->Type |= IMMEDIATE; do_macro((Macro *) cp); RecDepth++; DoKeys(); RecDepth--; InJoverc = o_InJoverc; Inputp = o_Inputp; strcpy(mesgbuf, o_mesgbuf); } else ExecCmd(cp); } #endif /* ExecNow */ private char **scanvec __(( char **_(args), const char *_(str) )); private char ** scanvec(args, str) register char **args; register const char *str; { while (*args) { if (strcmp(str, *args) == 0) return args; args++; } return NULL; } /* chkmail() returns nonzero if there is new mail since the last time we checked. */ #ifdef MAIL DEF_INT( "mail-check-frequency", MailInt, V_BASE10 ) _IF(def MAIL) = 60; /* check no more often than 60 seconds */ # if unix # ifndef MAILBOX_FMT # if hpux # define MAILBOX_FMT "/usr/mail/%s" # else # define MAILBOX_FMT "/usr/spool/mail/%s" # endif # endif # ifndef LOGIN_NAME # ifdef SYSV # define LOGIN_NAME "LOGNAME" # else # define LOGIN_NAME "USER" # endif # endif DEF_STR( "mailbox", Mailbox, 128, V_FILENAME ) _IF(def MAIL)_IF( unix)_IF(def PRIVATE) ZERO; /* initialized in main */ int chkmail(force) { static time_t last_chk ZERO; static int last_val ZERO; static off_t last_size ZERO; if (force || (now >= last_chk + MailInt)) { struct stat stbuf; register int old_val = last_val; register off_t old_size = last_size; last_chk = now; last_val = FALSE; last_size = 0; if (stat(Mailbox, &stbuf) == 0) { if ((stbuf.st_mtime > time0) && (stbuf.st_size > old_size) && (stbuf.st_mtime + 5 > stbuf.st_atime)) { last_val++; if (!old_val) dobell(3); } last_size = stbuf.st_size; } } return last_val; } # endif /* unix */ #endif /* MAIL */ DEF_INT( "update-time-frequency", UpdFreq, V_BASE10|V_MODELINE ) = 30; int inIOread ZERO; sig_tp updmode() { register unsigned freq; #ifdef RESIGNAL signal(SIGALRM, (sig_tp (*)__((int))) updmode); #endif updmodline(); if (freq = UpdFreq) freq -= (unsigned)(time(&now) % freq); /* NOTE: `now' should be updated BEFORE redisplay(). Also note that this assumes that `time_t' is a type that we can do arithmetic with, AND that it is an integral number of seconds. These assumptions hold on all Unix systems I know of (and vms, and DOS/Tos), and are guaranteed by Posix.1 (but NOT by ANSI C.) */ if (inIOread) redisplay(); /* {In order to be completely accurate, we should re-call time() and calculate `freq' AFTER the redisplay since that could in principle take a long time. In practice, however, most of the time it only has to update the current time in the modeline, which is fast enough. (all this to save a single time() system call...) */ alarm(freq); } void main(argc, argv) register char *argv[]; { extern int ModCount; register const char *cp; char ttbuf[TTBUFSIZ]; #ifndef BIG char s_iobuff[BLKSIZ], s_genbuf[LBSIZE]; /* The way I look at it, there ain't no way I is gonna run out of stack space UNLESS I have some kind of infinite recursive bug. So why use up some valuable memory, when there is plenty of space on the stack? (This only matters on wimpy pdp11's, of course.) */ iobuff = s_iobuff; genbuf = s_genbuf; #endif printf("\r[Setting up...] "); /* reassurance */ iniargc = argc; iniargv = argv; signal(SIGALRM, SIG_IGN); /* for now... */ if (setjmp(*mainjmp)) { printf("\rAck! I can't deal with error \"%s\" now.\r\n", mesgbuf); finish(0); } #ifdef FLAGS_LOWERCASE { /* * some shells (esp. Atari ST 1.0 desktop) convert arguments to * upper case, so we convert it back. Options are handled here * (for scanvec), file names are handled in UNIXcmd_line. We * cannot do it all here since for instance "-t tag" should not * be modified. {{Note that the lowercase conversion of file * names is independent of this compile-time option since (on * DOS) file names are case insignificant.}} */ register char **argp = argv; while (*argp) { if (**argp == '-' || **argp == '+') FIX_FILENAME(*argp); argp++; } } #endif #ifndef NOPROCS /* [TRH] handle piped input */ if (!isatty(0)) { pipe_fd = dup(0); close(0); # ifdef ATARIST dup2(-1, 0); /* sigh... */ # else open(DevTty, O_RDONLY); # endif } #endif d_cache_init(); /* initialize the disk buffer cache */ do_sgtty(); /* [TRH] need ospeed for setup decisions */ getTERM(); /* Get terminal. */ ttsize(); make_scr(); winit(); /* Initialize Window */ SetBuf(do_select(curwind, Mainbuf)); if ((HomeDir = getenv("HOME")) == NULL) #if unix HomeDir = Root; #else HomeDir = Home; #endif HomeLen = strlen(HomeDir); #if !unix dfollow(HomeDir, ttbuf); /* normalize dir.sep. */ if (ttbuf[HomeLen-1] == SLASH) ttbuf[--HomeLen] = '\0'; strcpy(HomeDir, ttbuf); # if !vms if ((cp = getenv("TMP")) || (cp = getenv("TMPDIR"))) PathParse(cp, TmpFilePath); if ((cp = getenv("JOVEDIR")) && *cp) { /* patch libdir */ # define REPLACE_DIR(d,f) \ PathParse(make_filename(ttbuf, d, basename(f)), f) REPLACE_DIR(cp, SystemRc); REPLACE_DIR(cp, CmdDb); REPLACE_DIR(cp, Recover); } # ifdef ATARIST if ((cp = getenv("PATH")) == NULL || strlen(cp) < 4) { /* supply a more meaningful PATH than the desktop does. */ extern char Path[]; /* from tune.c */ putenv(Path); } # endif /* ATARIST */ # endif /* !vms */ #endif /* !unix */ settout(ttbuf); /* buffered stdout */ #ifdef CHDIR { register char **argp; if ((((argp = scanvec(argv, "-d")) == NULL || (cp = argp[1], chdir(cp) != 0)) # if unix # ifndef cmp_ino && (((cp = getenv("CWD")) == NULL && (cp = getenv("PWD")) == NULL) || !cmp_ino(cp, ".")) # endif # endif ) || (!ISABSPATH(cp))) cp = getwd(genbuf); setCWD(cp); } #endif if (getenv("METAKEY")) MetaKey = ESC; #ifndef NOPROCS if (cp = getenv("SHELL")) Shell = (char *) cp; IShell = getenv("ESHELL"); /* ESHELL instead of ISHELL for GNUemacs compatibility. */ #endif #ifdef MAIL # if unix if ((cp = getenv("MAIL")) == NULL) { if ((cp = getenv(LOGIN_NAME)) == NULL) cp = basename(HomeDir); cp = copystr(sprint(MAILBOX_FMT, cp)); } Mailbox = (char *) cp; # endif #endif #ifdef RESHAPING RMargin = CO - 2; #endif joverc(SystemRc); if (!scanvec(argv, "-j")) { joverc(JoveRc); /* in HOME dir. */ if (!samefile(HomeDir, pwd())) /* avoid reading it twice */ # define CWD_JoveRc (JoveRc + 2) /* skip "~/" */ joverc(CWD_JoveRc); /* in CURRENT dir. */ } #ifndef FULLRECOVER if (scanvec(argv, "-r")) { /* AFTER joverc is read (for temp file) */ # if unix execl(Recover, "jove_recover", "-d", TmpFilePath, (char *)0); exec_fail(Recover); # else sprintf(genbuf, "%s -d %s", Recover, TmpFilePath); _exit(system(genbuf)); # endif /* unix */ } #endif /* FULLRECOVER */ #ifdef CHDIR_EXT dirs_init(); /* AFTER joverc is read (for "dirs-unique") */ #endif ModCount = 0; /* don't count modifications from .joverc */ ResetTerm(); /* initialize terminal (after ~/.joverc) */ /* setup signals */ #if unix || vms { static const Signal sigs[] = { # ifdef SIGHUP SIGHUP, finish, # endif SIGINT, finish, # ifdef SIGQUIT SIGQUIT, finish, # endif # ifdef SIGBUS SIGBUS, finish, # endif # ifdef SIGSEGV SIGSEGV, finish, # endif # ifdef SIGPIPE SIGPIPE, finish, # endif # ifdef SIGWINCH SIGWINCH, winch, # endif # ifdef SIGALRM SIGALRM, (sig_tp (*)__((int))) updmode, # endif SIGTERM, finish }; SetSigs(sigs, sizeof sigs / sizeof sigs[0]); } #else /* !(unix || vms) */ /* for Atari/MSDOS we only emulate SIGALRM and SIGINT (see atari_st.c) */ signal(SIGINT, finish); signal(SIGALRM, (sig_tp (*)__((int))) updmode); #endif /* unix */ #ifdef IPROCS pinit(); /* Pipes/process initialization--AFTER signal setup. */ #endif /* set things up to update the modeline every UpdFreq seconds */ updmode(); time0 = now; /* obtained in updmode(). */ ClAndRedraw(); /* start the redisplay process. */ DoKeys(); finish(0); } /*====================================================================== * $Log: jove.c,v $ * Revision 14.32.0.12 1994/06/24 17:55:02 tom * (do_cmdline): fix name of scratch buffer. * * Revision 14.32.0.10 1994/04/22 18:24:23 tom * (error,complain,confirm): use `va_register va_list'. * * Revision 14.32.0.9 1994/02/04 03:27:26 tom * (Posix signal): fix old-style prototype. * * Revision 14.32.0.6 1993/10/28 00:54:49 tom * do_cmdline, main: replace conditional strlwr() with FIX_FILENAME(). * * Revision 14.32 1993/07/06 00:53:06 tom * (finish): re-signal ourselves so we die properly; * (winch): new SIGWINCH handler; * (getch): handle pending window change; * (main): establish handlers conditionally on existence of their signals; * add handler for SIGQUIT. * * Revision 14.31 1993/02/18 01:42:30 tom * remove (void) casts; move BIFF code to tty.c; move settout() setup to * before joverc() handling; reorganize updmode(); lotsa random optimizations. * * Revision 14.30 1993/01/27 01:33:20 tom * cleanup whitespace; add dirs_init(); update global clock `now' in updmode(). * * Revision 14.28 1992/10/23 17:45:59 tom * convert to "port{ansi,defs}.h" conventions. * * Revision 14.27 1992/09/22 02:03:52 tom * replace CTL('Q') with `QuoteChar'; add some typecasts to suppress warnings. * * Revision 14.26 1992/08/26 23:56:55 tom * handle eventual window resize after jove has been suspended; use explicit * "i-shell" and "i-shell-flags" in "push-shell"; make iniarg[vc] private; * simplify ExecNow() due to bug fix in macro execution; * PRIVATE-ized some Variable defs; add RCS directives. * */