home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD1.bin
/
gnu
/
src
/
baseline
/
jove-4.14.6.lha
/
jove-4.14.6
/
jove.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-10
|
30KB
|
1,572 lines
/***************************************************************************
* This program is Copyright (C) 1986, 1987, 1988 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, and some system dependent
type things, e.g. putting terminal in CBREAK mode, etc. */
#include "jove.h"
#include "fp.h"
#include "termcap.h"
#include "ctype.h"
#include "chars.h"
#include "disp.h"
#include "re.h" /* for find_tag() */
#include "rec.h"
#ifdef IPROCS
# include "iproc.h"
#endif
#ifdef UNIX
#include "ttystate.h"
#endif
#ifdef SCO
#undef TIOCGWINSZ
#include <sys/stream.h>
#include <sys/ptem.h>
#endif
#ifdef MAC
# include "mac.h"
#else
# ifdef STDARGS
# include <stdarg.h>
# else
# include <varargs.h>
# endif
# include <sys/stat.h>
#endif
#include <signal.h>
#include <errno.h>
#ifdef MSDOS
# include <process.h>
#endif /* MSDOS */
#ifndef MAC
# include <fcntl.h>
#endif
#ifdef MSDOS
private void break_off proto((void)),
break_rst proto((void));
#endif
#ifdef MAC
# define WINRESIZE 1
#else
# ifdef TIOCGWINSZ
# ifdef SIGWINCH
# define WINRESIZE 1
# endif
# endif
#endif
private void
DoKeys proto((bool firsttime));
#ifdef MSDOS
extern
#else
private
#endif
void
UnsetTerm proto((char *)),
do_sgtty proto((void));
/* Various tty state structures.
* Each is an array, subscripted by one of "OFF" or "ON".
*/
#ifdef UNIX
# ifdef TIOCSLTC
struct ltchars ls[2];
# endif /* TIOCSLTC */
# ifdef TIOCGETC
struct tchars tc[2];
# endif
# ifdef PASS8 /* use pass8 instead of raw for meta-key */
private int lmword[2]; /* local mode word */
# endif
# ifdef BRLUNIX
struct sg_brl sg[2];
#endif
#ifdef TERMIO
struct termio sg[2];
#endif
#ifdef TERMIOS
struct termios sg[2];
#endif
#ifdef SGTTY
struct sgttyb sg[2];
#endif
# ifdef BIFF
private struct stat tt_stat; /* for biff */
# ifndef BSD4_2
private char *tt_name = NULL; /* name of the control tty */
extern char *ttyname(); /* for systems w/o fchmod ... */
# endif
private bool dw_biff = NO; /* whether or not to fotz at all */
# endif /* BIFF */
#endif /* UNIX */
bool errormsg;
char NullStr[] = "";
jmp_buf mainjmp;
#ifdef MSDOS
# define SIGHUP 99
# define SIGIOT 99
#endif /* MSDOS */
/* finish() does not return, so it is funny that it returns a non-void
* result. This is because most systems claim that signal(2) deals
* with functions of type int (). ANSI changes this: the function
* type must be void (int). This bridge must soon be crossed.
*/
SIGRESULT
finish(code)
int code;
{
int save_errno = errno; /* Subtle, but necessary! */
static int Crashing = 0; /* we are in the middle of crashing */
bool CoreDump = (code != 0 && code != SIGHUP),
DelTmps = YES; /* Usually we delete them. */
if (code == SIGINT) {
char c;
#ifdef PIPEPROCS
int started;
#endif
#ifndef MENLO_JCL
(void) signal(code, finish);
#endif
f_mess("Abort (Type 'n' if you're not sure)? ");
#ifndef MSDOS
# ifdef PIPEPROCS
started = kbd_stop();
# endif
#ifdef SYSV
if (read(0, (UnivPtr) &c, (size_t) 1) != 1)
#endif
(void) read(0, (UnivPtr) &c, (size_t) 1);
# ifdef PIPEPROCS
if (started)
(void) kbd_strt();
# endif
#else /* MSDOS */
c = getrawinchar();
#endif /* MSDOS */
message(NullStr);
if ((c & 0377) != 'y') {
redisplay();
errno = save_errno;
SIGRETURN;
}
}
DisabledRedisplay = YES;
#ifndef MAC
UnsetTerm(NullStr);
#endif
#ifdef PIPEPROCS
kbd_kill(); /* kill the keyboard process */
#endif
#ifndef MSDOS
if (code != 0) {
if (!Crashing) {
Crashing = YES;
lsave();
SyncRec();
writef("JOVE CRASH!! (code %d): %s\n", code,
strerror(errno));
if (ModBufs(YES)) {
writef("Your buffers have been saved.\n");
writef("Use \"jove -r\" to have a look at them.\n");
DelTmps = NO; /* Don't delete anymore. */
} else
writef("You didn't lose any work.\n");
} else
writef("\r\nYou may have lost your work!\n");
}
#endif /* MSDOS */
flushscreen();
if (DelTmps) {
#ifdef PTYPROCS
(void) signal(SIGCHLD, SIG_IGN);
#endif
tmpremove();
#ifndef MSDOS
recremove();
#endif /* MSDOS */
}
#ifdef UNIX
if (CoreDump)
abort();
#ifdef PROFILING
exit(0);
#else
_exit(0);
#endif
#else /* !UNIX */
#ifdef MSDOS
break_rst(); /* restore previous ctrl-c handling */
#endif
exit(0);
#endif /* !UNIX */
/*NOTREACHED*/
}
private char smbuf[20],
*bp = smbuf;
private int nchars = 0;
private char peekbuf[10],
*peekp = peekbuf;
#if defined(SYSV) || defined(M_XENIX)
#define NONBLOCKINGREAD 1
private void
setblock(fd, on) /* turn blocking on or off */
register int fd;
bool on;
{
static int blockf, nonblockf;
static bool first = TRUE;
if (first) {
int flags;
first = FALSE;
if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
finish(SIGHUP);
blockf = flags & ~O_NDELAY; /* make sure O_NDELAY is off */
nonblockf = flags | O_NDELAY; /* make sure O_NDELAY is on */
}
if (fcntl(fd, F_SETFL, on ? blockf : nonblockf) == -1)
finish(SIGHUP);
}
#endif /* defined(SYSV) || defined(M_XENIX) */
private int
Peekc()
{
return peekp == peekbuf? EOF : *--peekp & 0377;
}
void
Ungetc(c)
int c;
{
if (peekp != &peekbuf[(sizeof peekbuf) - 1])
*peekp++ = c;
}
bool InputPending = NO;
char *Inputp = NULL;
#ifdef PTYPROCS
int
jgetchar()
{
fd_set reads;
register int max = getdtablesize();
register int tmp,
nfds;
int c;
if (nchars <= 0) {
/* Get a character from the keyboard, first checking for
any input from a process. Handle that first, and then
deal with the terminal input. */
do {
do {
reads = global_fd;
nfds = select(max, &reads, (fd_set *)0, (fd_set *)0, (struct timeval *)NULL);
} while (nfds < 0 && errno == EINTR);
if (nfds == -1)
complain("\rerror in select %ld: %s", global_fd, strerror(errno));
else {
if (FD_ISSET(0, &reads)) {
nchars = read(0, (UnivPtr) smbuf, sizeof(smbuf));
FD_CLR(0, &reads);
nfds--;
}
for (tmp = 1; tmp < max; tmp++) {
if (FD_ISSET(tmp, &reads)) {
read_proc(tmp);
FD_CLR(tmp, &reads);
if (--nfds == 0)
break;
}
}
}
} while (nchars <= 0);
if (nchars <= 0)
finish(SIGHUP);
bp = smbuf;
InputPending = (nchars > 1);
}
if (((c = *bp) & 0200) && MetaKey) {
*bp = (c & CHARMASK);
return '\033';
}
nchars -= 1;
return *bp++ & 0377;
}
#else /* !PTYPROCS */
int
jgetchar()
{
register int c;
struct header {
int pid;
int nbytes;
} header;
normal:
if (nchars <= 0) {
bp = smbuf;
#ifdef MSDOS
*bp = getrawinchar();
nchars = 1;
#else /* !MSDOS */
# ifdef IPROCS
if (NumProcs > 0) {
for (;;) {
size_t n = f_readn(ProcInput, (char *) &header,
sizeof(header));
if (n != sizeof(header)) {
raw_complain("\r\nError reading kbd process, expected %d, got %d bytes\r\n", sizeof header, n);
finish(SIGHUP);
}
/* data is from the keyboard process */
if (header.pid == kbd_pid) {
nchars = f_readn(ProcInput, smbuf, header.nbytes);
if (nchars != header.nbytes) {
raw_complain("\r\nError reading kbd process, expected %d, got %d bytes.\r\n", header.nbytes, nchars);
finish(SIGHUP);
}
break;
}
read_proc(header.pid, header.nbytes);
if (NumProcs == 0) {
(void) kbd_stop();
goto normal;
}
}
} else /*...*/
# endif
/*...*/ {
for (;;) {
nchars = read(0, (UnivPtr) smbuf, sizeof smbuf);
if (nchars > 0)
break;
# ifdef SYSV
/* System V seems to allow zero-length results */
if (nchars == 0)
continue;
# endif /* SYSV */
/* retry on interrupt */
if (!(nchars < 0 && errno == EINTR))
finish(SIGHUP);
}
}
#endif /* !MSDOS */
InputPending = nchars > 0;
}
if (((c = *bp) & 0200) && MetaKey) {
*bp = (c & CHARMASK);
return '\033';
}
nchars -= 1;
return (*bp++ & CHARMASK);
}
#endif /* !PTYPROCS */
/* Returns non-zero if a character waiting */
bool
ch