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

📄 tty_pty.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (flag & IO_NDELAY)			return (EWOULDBLOCK);		if (error = tsleep((caddr_t)&tp->t_outq.c_cf, TTIPRI | PCATCH,		    ttyin, 0))			return (error);	}	if (pti->pt_flags & (PF_PKT|PF_UCNTL))		error = ureadc(0, uio);	while (uio->uio_resid > 0 && error == 0) {		cc = q_to_b(&tp->t_outq, buf, min(uio->uio_resid, BUFSIZ));		if (cc <= 0)			break;		error = uiomove(buf, cc, uio);	}	if (tp->t_outq.c_cc <= tp->t_lowat) {		if (tp->t_state&TS_ASLEEP) {			tp->t_state &= ~TS_ASLEEP;			wakeup((caddr_t)&tp->t_outq);		}		selwakeup(&tp->t_wsel);	}	return (error);}voidptsstop(tp, flush)	register struct tty *tp;	int flush;{	struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)];	int flag;	/* note: FLUSHREAD and FLUSHWRITE already ok */	if (flush == 0) {		flush = TIOCPKT_STOP;		pti->pt_flags |= PF_STOPPED;	} else		pti->pt_flags &= ~PF_STOPPED;	pti->pt_send |= flush;	/* change of perspective */	flag = 0;	if (flush & FREAD)		flag |= FWRITE;	if (flush & FWRITE)		flag |= FREAD;	ptcwakeup(tp, flag);}ptcselect(dev, rw, p)	dev_t dev;	int rw;	struct proc *p;{	register struct tty *tp = &pt_tty[minor(dev)];	struct pt_ioctl *pti = &pt_ioctl[minor(dev)];	int s;	if ((tp->t_state&TS_CARR_ON) == 0)		return (1);	switch (rw) {	case FREAD:		/*		 * Need to block timeouts (ttrstart).		 */		s = spltty();		if ((tp->t_state&TS_ISOPEN) &&		     tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) {			splx(s);			return (1);		}		splx(s);		/* FALLTHROUGH */	case 0:					/* exceptional */		if ((tp->t_state&TS_ISOPEN) &&		    (pti->pt_flags&PF_PKT && pti->pt_send ||		     pti->pt_flags&PF_UCNTL && pti->pt_ucntl))			return (1);		selrecord(p, &pti->pt_selr);		break;	case FWRITE:		if (tp->t_state&TS_ISOPEN) {			if (pti->pt_flags & PF_REMOTE) {			    if (tp->t_canq.c_cc == 0)				return (1);			} else {			    if (tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG-2)				    return (1);			    if (tp->t_canq.c_cc == 0 && (tp->t_iflag&ICANON))				    return (1);			}		}		selrecord(p, &pti->pt_selw);		break;	}	return (0);}ptcwrite(dev, uio, flag)	dev_t dev;	register struct uio *uio;	int flag;{	register struct tty *tp = &pt_tty[minor(dev)];	register u_char *cp;	register int cc = 0;	u_char locbuf[BUFSIZ];	int cnt = 0;	struct pt_ioctl *pti = &pt_ioctl[minor(dev)];	int error = 0;again:	if ((tp->t_state&TS_ISOPEN) == 0)		goto block;	if (pti->pt_flags & PF_REMOTE) {		if (tp->t_canq.c_cc)			goto block;		while (uio->uio_resid > 0 && tp->t_canq.c_cc < TTYHOG - 1) {			if (cc == 0) {				cc = min(uio->uio_resid, BUFSIZ);				cc = min(cc, TTYHOG - 1 - tp->t_canq.c_cc);				cp = locbuf;				error = uiomove((caddr_t)cp, cc, uio);				if (error)					return (error);				/* check again for safety */				if ((tp->t_state&TS_ISOPEN) == 0)					return (EIO);			}			if (cc)				(void) b_to_q((char *)cp, cc, &tp->t_canq);			cc = 0;		}		(void) putc(0, &tp->t_canq);		ttwakeup(tp);		wakeup((caddr_t)&tp->t_canq);		return (0);	}	while (uio->uio_resid > 0) {		if (cc == 0) {			cc = min(uio->uio_resid, BUFSIZ);			cp = locbuf;			error = uiomove((caddr_t)cp, cc, uio);			if (error)				return (error);			/* check again for safety */			if ((tp->t_state&TS_ISOPEN) == 0)				return (EIO);		}		while (cc > 0) {			if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 &&			   (tp->t_canq.c_cc > 0 || !(tp->t_iflag&ICANON))) {				wakeup((caddr_t)&tp->t_rawq);				goto block;			}			(*linesw[tp->t_line].l_rint)(*cp++, tp);			cnt++;			cc--;		}		cc = 0;	}	return (0);block:	/*	 * Come here to wait for slave to open, for space	 * in outq, or space in rawq.	 */	if ((tp->t_state&TS_CARR_ON) == 0)		return (EIO);	if (flag & IO_NDELAY) {		/* adjust for data copied in but not written */		uio->uio_resid += cc;		if (cnt == 0)			return (EWOULDBLOCK);		return (0);	}	if (error = tsleep((caddr_t)&tp->t_rawq.c_cf, TTOPRI | PCATCH,	    ttyout, 0)) {		/* adjust for data copied in but not written */		uio->uio_resid += cc;		return (error);	}	goto again;}/*ARGSUSED*/ptyioctl(dev, cmd, data, flag, p)	dev_t dev;	int cmd;	caddr_t data;	int flag;	struct proc *p;{	register struct tty *tp = &pt_tty[minor(dev)];	register struct pt_ioctl *pti = &pt_ioctl[minor(dev)];	register u_char *cc = tp->t_cc;	int stop, error;	/*	 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.	 * ttywflush(tp) will hang if there are characters in the outq.	 */	if (cmd == TIOCEXT) {		/*		 * When the EXTPROC bit is being toggled, we need		 * to send an TIOCPKT_IOCTL if the packet driver		 * is turned on.		 */		if (*(int *)data) {			if (pti->pt_flags & PF_PKT) {				pti->pt_send |= TIOCPKT_IOCTL;				ptcwakeup(tp, FREAD);			}			tp->t_lflag |= EXTPROC;		} else {			if ((tp->t_state & EXTPROC) &&			    (pti->pt_flags & PF_PKT)) {				pti->pt_send |= TIOCPKT_IOCTL;				ptcwakeup(tp, FREAD);			}			tp->t_lflag &= ~EXTPROC;		}		return(0);	} else	if (cdevsw[major(dev)].d_open == ptcopen)		switch (cmd) {		case TIOCGPGRP:			/*			 * We aviod calling ttioctl on the controller since,			 * in that case, tp must be the controlling terminal.			 */			*(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;			return (0);		case TIOCPKT:			if (*(int *)data) {				if (pti->pt_flags & PF_UCNTL)					return (EINVAL);				pti->pt_flags |= PF_PKT;			} else				pti->pt_flags &= ~PF_PKT;			return (0);		case TIOCUCNTL:			if (*(int *)data) {				if (pti->pt_flags & PF_PKT)					return (EINVAL);				pti->pt_flags |= PF_UCNTL;			} else				pti->pt_flags &= ~PF_UCNTL;			return (0);		case TIOCREMOTE:			if (*(int *)data)				pti->pt_flags |= PF_REMOTE;			else				pti->pt_flags &= ~PF_REMOTE;			ttyflush(tp, FREAD|FWRITE);			return (0);#ifdef COMPAT_43		case TIOCSETP:				case TIOCSETN:#endif		case TIOCSETD:		case TIOCSETA:		case TIOCSETAW:		case TIOCSETAF:			ndflush(&tp->t_outq, tp->t_outq.c_cc);			break;		case TIOCSIG:			if (*(unsigned int *)data >= NSIG)				return(EINVAL);			if ((tp->t_lflag&NOFLSH) == 0)				ttyflush(tp, FREAD|FWRITE);			pgsignal(tp->t_pgrp, *(unsigned int *)data, 1);			if ((*(unsigned int *)data == SIGINFO) &&			    ((tp->t_lflag&NOKERNINFO) == 0))				ttyinfo(tp);			return(0);		}	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);	if (error < 0)		 error = ttioctl(tp, cmd, data, flag);	if (error < 0) {		if (pti->pt_flags & PF_UCNTL &&		    (cmd & ~0xff) == UIOCCMD(0)) {			if (cmd & 0xff) {				pti->pt_ucntl = (u_char)cmd;				ptcwakeup(tp, FREAD);			}			return (0);		}		error = ENOTTY;	}	/*	 * If external processing and packet mode send ioctl packet.	 */	if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {		switch(cmd) {		case TIOCSETA:		case TIOCSETAW:		case TIOCSETAF:#ifdef COMPAT_43		case TIOCSETP:		case TIOCSETN:#endif#if defined(COMPAT_43) || defined(COMPAT_SUNOS)		case TIOCSETC:		case TIOCSLTC:		case TIOCLBIS:		case TIOCLBIC:		case TIOCLSET:#endif			pti->pt_send |= TIOCPKT_IOCTL;			ptcwakeup(tp, FREAD);		default:			break;		}	}	stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s')) 		&& CCEQ(cc[VSTART], CTRL('q'));	if (pti->pt_flags & PF_NOSTOP) {		if (stop) {			pti->pt_send &= ~TIOCPKT_NOSTOP;			pti->pt_send |= TIOCPKT_DOSTOP;			pti->pt_flags &= ~PF_NOSTOP;			ptcwakeup(tp, FREAD);		}	} else {		if (!stop) {			pti->pt_send &= ~TIOCPKT_DOSTOP;			pti->pt_send |= TIOCPKT_NOSTOP;			pti->pt_flags |= PF_NOSTOP;			ptcwakeup(tp, FREAD);		}	}	return (error);}

⌨️ 快捷键说明

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