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

📄 sh.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
	tp->t_state |= TS_WOPEN;	if ((tp->t_state&TS_ISOPEN) == 0) {	    shmodem[unit] = MODEM_DSR_START; /* prevents spurious startups */	}	tty_def_open(tp, dev, flag, (shsoftCAR[sh]&(1<<(unit&LINEMASK))));	shparam(unit);	/*	 * Wait for carrier, then process line discipline specific open.	 */	/*	 * Set up receive hold off timer. Manual says we have	 * to point to line 0 before we set the timer.	 */	addr->csr.low = SH_RIE|(0 & LINEMASK);	/* set to line 0 */	sh_softcsr = SH_RIE|(0 & LINEMASK);	addr->run.rxtimer = 10;			/* 10 MS hold off time */	s=spl5();	if (tp->t_cflag & CLOCAL) {		/* this is a local connection - ignore carrier */		tp->t_state |= TS_CARR_ON;		shmodem[unit] |= MODEM_CTS|MODEM_CD|MODEM_DSR;		addr->csr.low = SH_RIE|(unit & LINEMASK); /* set to line #*/		sh_softcsr = SH_RIE|(unit & LINEMASK); /* set to line #*/							  /* enable interrupts*/		addr->lnctrl &= ~(SH_MODEM);		addr->lnctrl |= (SH_DTR|SH_RTS|SH_REN);		/*	 	 * Set state bit to tell tty.c not to assign this line as the 	 	 * controlling terminal for the process which opens this line.	 	 */		if ((flag & O_NOCTTY) && (u.u_procp->p_progenv == A_POSIX))			tp->t_state |= TS_ONOCTTY;		splx(s);		return ((*linesw[tp->t_line].l_open)(dev, tp));	}/* NOTREACHED (softCAR and CLOCAL always set, i.e., no modem control) */	addr->csr.low = SH_RIE|(unit & LINEMASK);	sh_softcsr = SH_RIE|(unit & LINEMASK);	addr->lnctrl |= (SH_DTR|SH_RTS|SH_MODEM|SH_REN);	if ((flag & (O_NDELAY|O_NONBLOCK)) == 0) {		if (shdsr) {			if ((addr->fun.fs.stat)&SH_DSR) {				shmodem[unit] |= (MODEM_DSR_START|MODEM_DSR);				tp->t_dev = dev; /* need it for timeouts */				timeout(sh_dsr_check, tp, hz*30);				timeout(sh_dsr_check, tp, hz/2);			}		}		/*		 * Ignore DSR and immediately look for CD & CTS.		 */		else {			shmodem[unit] |= (MODEM_DSR_START|MODEM_DSR);			sh_dsr_check(tp);		}	}#ifdef SHDEBUG	if (shdebug)		mprintf("shopen:  line=%d, state=%x, pid=%d\n", unit,			tp->t_state, u.u_procp->p_pid);#endif	if (flag & (O_NDELAY|O_NONBLOCK))		tp->t_state |= TS_ONDELAY;	else		while ((tp->t_state&TS_CARR_ON)==0) {			inuse = tp->t_state&TS_INUSE;			sleep((caddr_t)&tp->t_rawq, TTIPRI); 			/* 			 * See if wakeup is due to a false call. 			 */ 			if (shmodem[unit]&MODEM_BADCALL){				splx(s); 				return(EWOULDBLOCK);			}			/* if we opened "block if in use"  and			 *  the terminal was not inuse at that time			 *  but is became "in use" while we were			 *  waiting for carrier then return			 */			if ((flag & O_BLKINUSE) && (inuse==0) &&				(tp->t_state&TS_INUSE)) {					splx(s);					return(EALREADY);			}		}	/*	 * Set state bit to tell tty.c not to assign this line as the 	 * controlling terminal for the process which opens this line.	 */	if ((flag & O_NOCTTY) && (u.u_procp->p_progenv == A_POSIX))		tp->t_state |= TS_ONOCTTY;	splx(s);	return ((*linesw[tp->t_line].l_open)(dev, tp));}/* * Close a SH line. *//*ARGSUSED*/shclose(dev, flag)	dev_t dev;	int flag;{	register struct tty *tp;	register int unit, s;	register struct shdevice *addr;	register sh;	extern int wakeup();	int turnoff = 0;	unit = minor(dev);	sh = unit >> 3;	tp = &sh_tty[unit];	addr = (struct shdevice *)tp->t_addr;	tp->t_state |= TS_CLOSING;	if (tp->t_line)		(*linesw[tp->t_line].l_close)(tp);	if ((tp->t_cflag&HUPCL) || (tp->t_state&TS_ISOPEN)==0) {		s = spl5();		turnoff++;		addr->csr.low = SH_RIE|(unit & LINEMASK);		sh_softcsr = SH_RIE|(unit & LINEMASK);		addr->lnctrl &= ~(SH_DTR|SH_RTS);  /* turn off DTR */		tp->t_state &= ~TS_CARR_ON; /* prevents recv intr. timeouts */		if ((tp->t_cflag & CLOCAL) == 0) {#ifdef SHDEBUG	if (shdebug)		mprintf("shclose: DTR drop line=%d, state=%x, pid=%d\n", unit,			tp->t_state, u.u_procp->p_pid);#endif			/* wait an additional 5 seconds for DSR to drop */			if (shdsr && (addr->fun.fs.stat&SH_DSR)) {				timeout(wakeup, (caddr_t) &tp->t_dev, 5*hz);				sleep((caddr_t)&tp->t_dev, PZERO-10);			}			timeout(wakeup, (caddr_t) &tp->t_dev, hz/5);			sleep((caddr_t)&tp->t_dev, PZERO-10);		}		splx(s);	}#ifdef SHDEBUG	if (shdebug)		mprintf("shclose: line=%d, state=%x, pid=%d\n", unit,			tp->t_state, u.u_procp->p_pid);#endif	shsoftCAR[sh] &= ~(1<<(unit&LINEMASK));	shsoftCAR[sh] |= (1<<(unit&LINEMASK)) & shdefaultCAR[sh];	ttyclose(tp);  /* remember this will clear out t_state */	if (turnoff) {		/* we have to do this after the ttyclose so that output		 * can still drain		 */		s = spl5();		addr->csr.low = SH_RIE|(unit & LINEMASK);		addr->lnctrl = NULL; /* turn off interrupts also */		splx(s);	}	shmodem[unit] = 0;	tty_def_close(tp);	wakeup((caddr_t)&tp->t_rawq); /* wake up anyone in shopen */}shread(dev, uio)	dev_t dev;	struct uio *uio;{	register struct tty *tp = &sh_tty[minor(dev)];	return ((*linesw[tp->t_line].l_read)(tp, uio));}shwrite(dev, uio)	dev_t dev;	struct uio *uio;{	register struct tty *tp = &sh_tty[minor(dev)];	return ((*linesw[tp->t_line].l_write)(tp, uio));}/* * SH receiver interrupt. */shrint(sh)	int sh; /* module number */{	register struct tty *tp;	register c, unit;	register struct shdevice *addr;	struct tty *tp0;	register struct uba_device *ui;	register flg;	int overrun = 0;	u_char *modem0, *modem;	int modem_cont;	ui = shinfo[sh];	if (ui == 0 || ui->ui_alive == 0)		return;	addr = (struct shdevice *)shmem;	tp0 = &sh_tty[sh<<3];  /* first tty structure that corresponds				* to this sh module				*/	modem0 = &shmodem[sh<<3];	/*	 * Loop fetching characters from receive fifo for this	 * sh until there are no more in the receive fifo.	 */	while ((c = addr->run.rbuf) < 0) {		/* if c < 0 then data valid is set */		unit = (c>>8)&LINEMASK;		tp = tp0 + unit; /* tty struct for this line */		flg = tp->t_iflag;		modem = modem0 + unit;		modem_cont = 0;#ifdef SHDEBUG		if (shdebug > 6)			mprintf("shrint0: c=%x, tp=%x\n", c, tp);#endif		/* check for modem transitions */		if ((c & SH_STAT)==SH_STAT) {			if (c & SH_DIAG) /* ignore diagnostic info */				continue;#ifdef SHDEBUG			if (shdebug > 6)				mprintf("shrint: c=%x, tp=%x\n", c, tp);#endif			if (tp->t_cflag & CLOCAL)				continue;			/* set to line #*/			addr->csr.low = SH_RIE|(unit & LINEMASK);			sh_softcsr = SH_RIE|(unit & LINEMASK);			/* examine modem status */						/*			 * Drop DTR immediately if DSR has gone away.			 * If really an active close then do not			 *    send signals.			 */			if ((addr->fun.fs.stat&SH_DSR)==0) {				if (tp->t_state&TS_CLOSING) {					untimeout(wakeup, (caddr_t) &tp->t_dev);					wakeup((caddr_t) &tp->t_dev);					continue;				}				if (tp->t_state&TS_CARR_ON) {					/*					 * Only drop line if DSR is followed.					 */					if (shdsr)						sh_tty_drop(tp);					continue;				}			}			/*			 * Check for transient CD drops.			 * Only drop DTR if CD is down for more than 2 secs.			 */			if (tp->t_state&TS_CARR_ON)			    if ((addr->fun.fs.stat&SH_CD)==0){				if ( *modem & MODEM_CD) {				    /* only start timer once */				    if (shdebug)					mprintf("shrint, cd_drop, tp=%x\n", tp);				    *modem &= ~MODEM_CD;				    shtimestamp[minor(tp->t_dev)] = time;				    timeout(sh_cd_drop, tp, hz*shcdtime);				    modem_cont = 1;;				}			    } else				/*				 * CD has come up again.				 * Stop timeout from occurring if set.				 * If interval is more than 2 secs then				 *  drop DTR.				 */				if ((*modem&MODEM_CD)==0) {					untimeout(sh_cd_drop, tp);					if (sh_cd_down(tp))						/* drop connection */						sh_tty_drop(tp);					*modem |= MODEM_CD;					modem_cont = 1;;				}			/* CTS flow control check */			if (tp->t_state&TS_CARR_ON)				if ((addr->fun.fs.stat&SH_CTS)==0) {					tp->t_state |= TS_TTSTOP;					*modem &= ~MODEM_CTS;					if (shdebug)					   mprintf("shrint: CTS stop, tp=%x\n", tp);					shstop(tp, 0);					continue;				} else if ((*modem&MODEM_CTS)==0) {					    tp->t_state &= ~TS_TTSTOP;					    *modem |= MODEM_CTS;					    if (shdebug)					       mprintf("shrint: CTS start, tp=%x\n", tp);					    shstart(tp);					    continue;					}			/*			 * Avoid calling sh_start_tty for a CD transition if			 * the connection has already been established.			 */			if (modem_cont)				continue;			/*			 * If 500 ms timer has not expired then dont			 * check anything yet.			 * Check to see if DSR|CTS|CD are asserted.			 * If so we have a live connection.			 * If DSR is set for the first time we allow			 * 30 seconds for a live connection.			 */			if (shdsr) {				if ((addr->fun.fs.stat&SH_XMIT)==SH_XMIT				    && (*modem&MODEM_DSR_START)==0)					sh_start_tty(tp);				else				    if ((addr->fun.fs.stat&SH_DSR) &&					(*modem&MODEM_DSR)==0) {					*modem |= (MODEM_DSR_START|MODEM_DSR);					/*					 * we should not look for CTS|CD for					 * about 500 ms.					 */					timeout(sh_dsr_check, tp, hz*30);					timeout(sh_dsr_check, tp, hz/2);				    }			}			/*			 * Ignore DSR but look for CD and CTS.			 */			else {				if ((addr->fun.fs.stat&SH_NODSR)==SH_NODSR)					sh_start_tty(tp);			}			continue;		}#ifndef PORTSELECTOR		if ((tp->t_state&TS_ISOPEN)==0) {#else		if ((tp->t_state&(TS_ISOPEN|TS_WOPEN))==0) {#endif			wakeup((caddr_t)tp);			continue;		}/*		This code handles the following termio input flags.  Also *		listed is what the default should be for propper Ultrix *		backward compatibility. * *		IGNBRK		FALSE *		BRKINT		TRUE *		IGNPAR		TRUE *		PARMRK		FALSE *		INPCK		TRUE *		ISTRIP		TRUE 		 */					/* tp->t_flags should be register */		/* SH_FERR is interpreted as a break */		if (c & SH_FERR) {			/*			 * If configured for trusted path, initiate			 * trusted path handling.			 */			if (do_tpath) {				tp->t_tpath |= TP_DOSAK;				(*linesw[tp->t_line].l_rint)(c, tp);				break;			}			if (flg & IGNBRK)				continue;			if (flg & BRKINT) {#ifdef SHDEBUG				if (shdebug)					mprintf("shrint: BREAK RECEIVED\n");#endif SHDEBUG				if ((tp->t_lflag_ext & PRAW) && 					(tp->t_line != TERMIODISC))					c = 0;				else {				    ttyflush(tp, FREAD|FWRITE);#ifdef SHDEBUG				    if (shdebug)					mprintf("sending signal to tp->t_pgrp = %d\n", tp->t_pgrp);#endif SHDEBUG				    gsignal(tp->t_pgrp, SIGINT);				    continue;				}			}			/*			 * TERMIO: If neither IGNBRK or BRKINT is set, a			 * break condition is read as a single '\0',			 * or if PARMRK is set as '\377','\0,'\0'.			 */			else {				if (flg & PARMRK){					(*linesw[tp->t_line].l_rint)(0377,tp);					(*linesw[tp->t_line].l_rint)(0,tp);				}				c = 0;			}				}		/* Parity Error */		else if (c & SH_PERR){			/* 

⌨️ 快捷键说明

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