⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jove.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** * 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	MSDOSprivate	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#endifprivate void	DoKeys proto((bool firsttime));#ifdef	MSDOSextern#elseprivate#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	TIOCSLTCstruct ltchars	ls[2];# endif	/* TIOCSLTC */# ifdef	TIOCGETCstruct tchars	tc[2];# endif# ifdef	PASS8			/* use pass8 instead of raw for meta-key */private int	lmword[2];		/* local mode word */# endif# ifdef	BRLUNIXstruct sg_brl	sg[2];#endif#ifdef TERMIOstruct termio	sg[2];#endif#ifdef TERMIOSstruct termios	sg[2];#endif#ifdef SGTTYstruct sgttyb	sg[2];#endif# ifdef	BIFFprivate struct stat	tt_stat;	/* for biff */#  ifndef	BSD4_2private char	*tt_name = NULL;		/* name of the control tty */extern char	*ttyname();		/* for systems w/o fchmod ... */#  endifprivate 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. */SIGRESULTfinish(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	1private voidsetblock(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 intPeekc(){	return peekp == peekbuf? EOF : *--peekp & 0377;}voidUngetc(c)int	c;{	if (peekp != &peekbuf[(sizeof peekbuf) - 1])		*peekp++ = c;}bool	InputPending = NO;char	*Inputp = NULL;#ifdef	PTYPROCSintjgetchar(){	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 */intjgetchar(){	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 */boolcharp(){	bool	some = NO;	if (InJoverc != 0 || nchars > 0 || Inputp != NULL)		return YES;#ifdef	BRLUNIX	{		static struct sg_brl gttyBuf;		gtty(0, (char *) &gttyBuf);		if (gttyBuf.sg_xflags & INWAIT)			some = YES;	}#else#ifdef	FIONREAD	{		long c;		if (ioctl(0, FIONREAD, (UnivPtr) &c) == -1)			c = 0;		some = (c > 0);	}#else#ifdef	NONBLOCKINGREAD	setblock(0, OFF);		/* turn blocking off */	nchars = read(0, (UnivPtr) smbuf, sizeof smbuf);	/* Is anything there? */	setblock(0, ON);		/* turn blocking on */	if (nchars > 0)		/* something was there */	    bp = smbuf;		/* make sure bp points to it */	some = (nchars > 0);	/* just say we found something */#else#ifdef	c70	some = !empty(0);#else#ifdef	MSDOS	some = rawkey_ready();#else#ifdef	MAC	some = rawchkc();#endif#endif#endif#endif#endif#endif	return some;}#ifdef	BIFFprivate void	biff_init proto((void));#endif#ifdef	TERMCAPprivate voidResetTerm(){	do_sgtty();		/* this is so if you change baudrate or stuff				   like that, JOVE will notice. */	ttyset(ON);	putpad(TI, 1);	putpad(VS, 1);	putpad(KS, 1);#ifdef	UNIX	(void) chkmail(YES);	/* force it to check to we can be accurate */#endif#ifdef	BIFF	if (BiffChk != dw_biff)		biff_init();	/* just in case we changed our minds about whether to deal with	   biff */#endif}private voidUnsetTerm(mesg)char	*mesg;{	ttyset(OFF);#ifdef	ID_CHAR	INSmode(NO);#endif	putpad(KE, 1);	putpad(VE, 1);	Placur(ILI, 0);	putpad(CE, 1);	if (TE)		putpad(TE, 1);	if (mesg[0] != '\0')		writef("%s\n", mesg);	flushscreen();}#endif	/* TERMCAP */#ifdef	JOB_CONTROLvoidPauseJove(){	UnsetTerm(ModBufs(NO) ? "[There are modified buffers]" : NullStr);	(void) kill(0, SIGTSTP);	ResetTerm();	ClAndRedraw();}#endif#ifndef	MACvoidjcloseall(){	tmpclose();#ifdef UNIX	recclose();#endif#ifdef	LOAD_AV	closekmem();#endif	/* LOAD_AV */}voidPush(){#ifndef	MSDOS	int	pid;	SIGRESULT	(*old_quit) ptrproto((int)) = signal(SIGQUIT, SIG_IGN);#endif	/* !MSDOS */	SIGRESULT	(*old_int) ptrproto((int)) = signal(SIGINT, SIG_IGN);# ifdef	PIPEPROCS	int	started;# endif#ifndef	MSDOS#ifdef	IPROCS	SigHold(SIGCHLD);#endif#ifdef	WINRESIZE	SigHold(SIGWINCH);#endif	alarm((unsigned)0);# ifdef	PIPEPROCS	started = kbd_stop();# endif	switch (pid = fork()) {	case -1:# ifdef	PIPEPROCS		if (started)			(void) kbd_strt();# endif		complain("[Fork failed: %s]", strerror(errno));		/*NOTREACHED*/	case 0:		UnsetTerm(ModBufs(NO) ? "[There are modified buffers]" : NullStr);#ifdef	WINRESIZE		SigRelse(SIGWINCH);#endif#ifdef	IPROCS		SigRelse(SIGCHLD);#endif		(void) signal(SIGTERM, SIG_DFL);#else	/* MSDOS */		UnsetTerm(ModBufs(NO) ? "[There are modified buffers]" : NullStr);#endif	/* MSDOS */		(void) signal(SIGINT, SIG_DFL);#ifdef	UNIX		(void) signal(SIGQUIT, SIG_DFL);		jcloseall();		/* note that curbuf->bfname may be NULL */		execl(Shell, basename(Shell), "-is", pr_name(curbuf->b_fname, NO),			(char *)NULL);		raw_complain("[Execl failed: %s]", strerror(errno));		_exit(1);	}#ifdef	IPROCS	SigRelse(SIGCHLD);#endif	dowait(pid, (int *) NULL);#endif	/* UNIX */#ifdef	MSDOS	break_rst();	if (spawnl(0, Shell, basename(Shell), (char *)NULL) == -1)		message("[Spawn failed]");#endif	/* MSDOS */#ifndef	MAC	ResetTerm();#endif#ifdef	WINRESIZE	SigRelse(SIGWINCH);#endif	ClAndRedraw();#ifndef	MSDOS	(void) signal(SIGQUIT, old_quit);#else	/* MSDOS */	break_off();	getCWD();#endif	/* MSDOS */	(void) signal(SIGINT, old_int);#ifdef UNIX	if (UpdFreq != 0)		(void) alarm((unsigned) (UpdFreq - (time((time_t *)NULL) % UpdFreq)));#endif# ifdef	PIPEPROCS	if (started)		(void) kbd_strt();# endif}#endif	/* MAC */bool	OKXonXoff = OFF;	/* ^S and ^Q initially DON'T work */int	IntChar = CTL(']');private voidttsize(){#ifdef	UNIX#   ifdef	TIOCGWINSZ	struct winsize win;	if (ioctl(0, TIOCGWINSZ, (UnivPtr) &win) == 0) {		if (win.ws_col)			CO = win.ws_col;		if (win.ws_row)			LI = win.ws_row;	}#   else	/* !TIOCGWINSZ */#	ifdef	BTL_BLIT#include <sys/jioctl.h>	struct jwinsize jwin;	if (ioctl(0, JWINSIZE, &jwin) == 0) {		if (jwin.bytesx)			CO = jwin.bytesx;		if (jwin.bytesy)			LI = jwin.bytesy;	}#	endif	/* BTL_BLIT */#   endif	/* !TIOCGWINSZ */#endif	/* UNIX */#ifdef	MAC	CO = getCO();	/* see mac.c */	LI = getLI();	Windchange = YES;	clr_page();#endif	ILI = LI - 1;}#ifdef	BIFFprivate voidbiff_init(){	dw_biff = ((BiffChk) &&#   ifndef	BSD4_2		   ((tt_name != NULL) || (tt_name = ttyname(0))) &&		   (stat(tt_name, &tt_stat) != -1) &&#   else		   (fstat(0, &tt_stat) != -1) &&#   endif		   (tt_stat.st_mode & S_IEXEC));	/* he's using biff */}private voidbiff(on)int	on;{	if (dw_biff == NO)		return;#   ifndef	BSD4_2	(void) chmod(tt_name, on ? tt_stat.st_mode :				   (tt_stat.st_mode & ~S_IEXEC));#   else	(void) fchmod(0, on ? tt_stat.st_mode :			      (tt_stat.st_mode & ~S_IEXEC));#   endif}#endif	/* BIFF */private voidttinit(){#ifdef	BIFF	biff_init();#endif#ifdef	TIOCSLTC	(void) ioctl(0, TIOCGLTC, (UnivPtr) &ls[OFF]);	ls[ON] = ls[OFF];	ls[ON].t_suspc = (char) -1;	ls[ON].t_dsuspc = (char) -1;	ls[ON].t_flushc = (char) -1;	ls[ON].t_lnextc = (char) -1;#endif#ifdef	TIOCGETC	/* Change interupt and quit. */	(void) ioctl(0, TIOCGETC, (UnivPtr) &tc[OFF]);	tc[ON] = tc[OFF];	tc[ON].t_intrc = IntChar;	tc[ON].t_quitc = (char) -1;	if (OKXonXoff) {		tc[ON].t_stopc = (char) -1;		tc[ON].t_startc = (char) -1;	}#endif	/* TIOCGETC */	do_sgtty();}private int	done_ttinit = NO;#ifndef	MSDOSprivate#endifvoiddo_sgtty(){#ifdef	UNIX# ifdef	TERMIO	(void) ioctl(0, TCGETA, (char *) &sg[OFF]);# endif# ifdef TERMIOS	(void) tcgetattr(0, &sg[OFF]);# endif# ifdef SGTTY	(void) gtty(0, &sg[OFF]);# endif	/* SYSV */	sg[ON] = sg[OFF];# ifdef	LPASS8	(void) ioctl(0, TIOCLGET, (UnivPtr) &lmword[OFF]);	lmword[ON] = lmword[OFF];	if (MetaKey)		lmword[ON] |= LPASS8;# endif# ifdef LTILDE	if (Hazeltine)		lmword[ON] &= ~LTILDE;# endif# if defined(TERMIO) || defined(TERMIOS)#ifdef TAB3	TABS = !((sg[OFF].c_oflag & TAB3) == TAB3);#endif#ifdef CBAUD	ospeed = sg[OFF].c_cflag & CBAUD;#endif	if (OKXonXoff)		sg[ON].c_iflag &= ~(IXON | IXOFF);	sg[ON].c_iflag &= ~(INLCR|ICRNL|IGNCR|ISTRIP);	/* sg[ON].c_lflag &= ~(ICANON|ECHO); */	sg[ON].c_cflag &= ~(CSIZE|PARENB);	sg[ON].c_cflag |= CS8;	sg[ON].c_lflag &= ~(ISIG|ICANON|ECHO|IEXTEN);#ifndef OCRNL#define OCRNL 0#endif	sg[ON].c_oflag &= ~(OCRNL|ONLCR);#  ifdef _POSIX_VDISABLE	/* The following characters cause signals in System Vr4.	 * We should perhaps handle them; for now, we suppress them.	 */	sg[ON].c_cc[VQUIT] = _POSIX_VDISABLE;#ifdef VSWTCH	sg[ON].c_cc[VSWTCH] = _POSIX_VDISABLE;#endif	sg[ON].c_cc[VSUSP] = _POSIX_VDISABLE;	sg[ON].c_cc[VDSUSP] = _POSIX_VDISABLE;#  else	sg[ON].c_cc[VINTR] = IntChar;	sg[ON].c_cc[VQUIT] = (char) -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -