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

📄 tty_chu.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
字号:
/* tty_chu.c,v 3.1 1993/07/06 01:07:30 jbj Exp * tty_chu.c - CHU line driver */#include "chu.h"#if NCHU > 0#include "../h/param.h"#include "../h/types.h"#include "../h/systm.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/ioctl.h"#include "../h/tty.h"#include "../h/proc.h"#include "../h/file.h"#include "../h/conf.h"#include "../h/buf.h"#include "../h/uio.h"#include "../h/chudefs.h"/* * Line discipline for receiving CHU time codes. * Does elementary noise elimination, takes time stamps after * the arrival of each character, returns a buffer full of the * received 10 character code and the associated time stamps. */#define	NUMCHUBUFS	3struct chudata {	u_char used;		/* Set to 1 when structure in use */	u_char lastindex;	/* least recently used buffer */	u_char curindex;	/* buffer to use */	u_char sleeping;	/* set to 1 when we're sleeping on a buffer */	struct chucode chubuf[NUMCHUBUFS];} chu_data[NCHU];/* * Number of microseconds we allow between * character arrivals.  The speed is 300 baud * so this should be somewhat more than 30 msec */#define	CHUMAXUSEC	(50*1000)	/* 50 msec */int chu_debug = 0;/* * Open as CHU time discipline.  Called when discipline changed * with ioctl, and changes the interpretation of the information * in the tty structure. *//*ARGSUSED*/chuopen(dev, tp)	dev_t dev;	register struct tty *tp;{	register struct chudata *chu;	/*	 * Don't allow multiple opens.  This will also protect us	 * from someone opening /dev/tty	 */	if (tp->t_line == CHULDISC)		return (EBUSY);	ttywflush(tp);	for (chu = chu_data; chu < &chu_data[NCHU]; chu++)		if (!chu->used)			break;	if (chu >= &chu[NCHU])		return (EBUSY);	chu->used++;	chu->lastindex = chu->curindex = 0;	chu->sleeping = 0;	chu->chubuf[0].ncodechars = 0;	tp->T_LINEP = (caddr_t) chu;	return (0);}/* * Break down... called when discipline changed or from device * close routine. */chuclose(tp)	register struct tty *tp;{	register int s = spl5();	((struct chudata *) tp->T_LINEP)->used = 0;	tp->t_cp = 0;	tp->t_inbuf = 0;	tp->t_rawq.c_cc = 0;		/* clear queues -- paranoid */	tp->t_canq.c_cc = 0;	tp->t_line = 0;			/* paranoid: avoid races */	splx(s);}/* * Read a CHU buffer.  Sleep on the current buffer */churead(tp, uio)	register struct tty *tp;	struct uio *uio;{	register struct chudata *chu;	register struct chucode *chucode;	register int s;	if ((tp->t_state&TS_CARR_ON)==0)		return (EIO);	chu = (struct chudata *) (tp->T_LINEP);	s = spl5();	chucode = &(chu->chubuf[chu->lastindex]);	while (chu->curindex == chu->lastindex) {		chu->sleeping = 1;		sleep((caddr_t)chucode, TTIPRI);	}	chu->sleeping = 0;	if (++(chu->lastindex) >= NUMCHUBUFS)		chu->lastindex = 0;	splx(s);	return (uiomove((caddr_t)chucode, sizeof(*chucode), UIO_READ, uio));}/* * Low level character input routine. * If the character looks okay, grab a time stamp.  If the stuff in * the buffer is too old, dump it and start fresh.  If the character is * non-BCDish, everything in the buffer too. */chuinput(c, tp)	register int c;	register struct tty *tp;{	register struct chudata *chu = (struct chudata *) tp->T_LINEP;	register struct chucode *chuc;	register int i;	long sec, usec;	struct timeval tv;	/*	 * Do a check on the BSDness of the character.  This delays	 * the time stamp a bit but saves a fair amount of overhead	 * when the static is bad.	 */	if (((c) & 0xf) > 9 || (((c)>>4) & 0xf) > 9) {		chuc = &(chu->chubuf[chu->curindex]);		chuc->ncodechars = 0;	/* blow all previous away */		return;	}	/*	 * Call microtime() to get the current time of day	 */	microtime(&tv);	/*	 * Compute the difference in this character's time stamp	 * and the last.  If it exceeds the margin, blow away all	 * the characters currently in the buffer.	 */	chuc = &(chu->chubuf[chu->curindex]);	i = (int)chuc->ncodechars;	if (i > 0) {		sec = tv.tv_sec - chuc->codetimes[i-1].tv_sec;		usec = tv.tv_usec - chuc->codetimes[i-1].tv_usec;		if (usec < 0) {			sec -= 1;			usec += 1000000;		}		if (sec != 0 || usec > CHUMAXUSEC) {			i = 0;			chuc->ncodechars = 0;		}	}	/*	 * Store the character.  If we're done, have to tell someone	 */	chuc->codechars[i] = (u_char)c;	chuc->codetimes[i] = tv;	if (++i < NCHUCHARS) {		/*		 * Not much to do here.  Save the count and wait		 * for another character.		 */		chuc->ncodechars = (u_char)i;	} else {		/*		 * Mark this buffer full and point at next.  If the		 * next buffer is full we overwrite it by bumping the		 * next pointer.		 */		chuc->ncodechars = NCHUCHARS;		if (++(chu->curindex) >= NUMCHUBUFS)			chu->curindex = 0;		if (chu->curindex == chu->lastindex)			if (++(chu->lastindex) >= NUMCHUBUFS)				chu->lastindex = 0;		chu->chubuf[chu->curindex].ncodechars = 0;		/*		 * Wake up anyone sleeping on this.  Also wake up		 * selectors and/or deliver a SIGIO as required.		 */		if (tp->t_rsel) {			selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL);			tp->t_state &= ~TS_RCOLL;			tp->t_rsel = 0;		}		if (tp->t_state & TS_ASYNC)			gsignal(tp->t_pgrp, SIGIO);		if (chu->sleeping)			(void) wakeup((caddr_t)chuc);	}}/* * Handle ioctls.  We reject all tty-style except those that * change the line discipline. */chuioctl(tp, cmd, data, flag)	struct tty *tp;	int cmd;	caddr_t data;	int flag;{	if ((cmd>>8) != 't')		return (-1);	switch (cmd) {	case TIOCSETD:	case TIOCGETD:	case TIOCGETP:	case TIOCGETC:		return (-1);	}	return (ENOTTY);	/* not quite appropriate */}chuselect(dev, rw)	dev_t dev;	int rw;{	register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)];	struct chudata *chu;	int s = spl5();	chu = (struct chudata *) (tp->T_LINEP);	switch (rw) {	case FREAD:		if (chu->curindex != chu->lastindex)			goto win;		if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait)			tp->t_state |= TS_RCOLL;		else			tp->t_rsel = u.u_procp;		break;	case FWRITE:		goto win;	}	splx(s);	return (0);win:	splx(s);	return (1);}#endif NCHU

⌨️ 快捷键说明

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