--- Net2/kern/tty_pty.c 2018/04/24 18:09:09 1.1.1.4 +++ Net2/kern/tty_pty.c 2018/04/24 18:14:47 1.1.1.5 @@ -30,24 +30,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)tty_pty.c 7.21 (Berkeley) 5/30/91 - * - * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE - * -------------------- ----- ---------------------- - * CURRENT PATCH LEVEL: 5 00094 - * -------------------- ----- ---------------------- - * - * 11 Dec 92 Williams Jolitz Fixed tty handling - * - * 28 Nov 1991 Warren Toomey Cleaned up the use of COMPAT_43 - * in the 386BSD kernel. - * 6 Oct 1992 Holger Veit Fixed 'hanging console' bug - * 11 Jan 93 Julian Elischer Fixes multiple processes on one - * pty bug - * 27 Feb 93 Charles Hannum Proper return values for ptsclose() - * and ptcclose() + * from: @(#)tty_pty.c 7.21 (Berkeley) 5/30/91 + * tty_pty.c,v 1.11 1993/07/19 05:52:32 mycroft Exp */ -static char rcsid[] = "$Header: /var/lib/cvsd/net2/Net2/kern/tty_pty.c,v 1.1.1.4 2018/04/24 18:09:09 root Exp $"; /* * Pseudo-teletype Driver @@ -59,6 +44,7 @@ static char rcsid[] = "$Header: /var/lib #include "param.h" #include "systm.h" #include "ioctl.h" +#include "select.h" #include "tty.h" #include "conf.h" #include "file.h" @@ -78,26 +64,30 @@ static char rcsid[] = "$Header: /var/lib * pts == /dev/tty[pqrs]? * ptc == /dev/pty[pqrs]? */ -struct tty pt_tty[NPTY]; +struct tty *pt_tty[NPTY]; struct pt_ioctl { int pt_flags; - pid_t pt_selr, pt_selw; + struct selinfo pt_selr, pt_selw; u_char pt_send; u_char pt_ucntl; } pt_ioctl[NPTY]; int npty = NPTY; /* for pstat -t */ -#define PF_RCOLL 0x01 -#define PF_WCOLL 0x02 +#define PF_COPEN 0x01 /* master open */ +#define PF_SOPEN 0x02 /* slave open */ #define PF_PKT 0x08 /* packet mode */ #define PF_STOPPED 0x10 /* user told stopped */ #define PF_REMOTE 0x20 /* remote and flow controlled input */ #define PF_NOSTOP 0x40 #define PF_UCNTL 0x80 /* user control mode */ +void ptcwakeup __P((struct tty *tp, int flag)); + /*ARGSUSED*/ +int ptsopen(dev, flag, devtype, p) dev_t dev; + int flag, devtype; struct proc *p; { register struct tty *tp; @@ -108,7 +98,10 @@ ptsopen(dev, flag, devtype, p) #endif if (minor(dev) >= NPTY) return (ENXIO); - tp = &pt_tty[minor(dev)]; + if(!pt_tty[minor(dev)]) { + tp = pt_tty[minor(dev)] = ttymalloc(); + } else + tp = pt_tty[minor(dev)]; if ((tp->t_state & TS_ISOPEN) == 0) { tp->t_state |= TS_WOPEN; ttychars(tp); /* Set up default chars */ @@ -126,15 +119,18 @@ ptsopen(dev, flag, devtype, p) tp->t_state |= TS_WOPEN; if (flag&FNONBLOCK) break; - if (error = ttysleep(tp, (caddr_t)&tp->t_raw, TTIPRI | PCATCH, + if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, ttopen, 0)) return (error); } - error = (*linesw[tp->t_line].l_open)(dev, tp, flag); + if (error = (*linesw[tp->t_line].l_open)(dev, tp)) + return (error); + pt_ioctl[minor(dev)].pt_flags |= PF_SOPEN; ptcwakeup(tp, FREAD|FWRITE); - return (error); + return (0); } +int ptsclose(dev, flag, mode, p) dev_t dev; int flag, mode; @@ -142,19 +138,26 @@ ptsclose(dev, flag, mode, p) { register struct tty *tp; - tp = &pt_tty[minor(dev)]; + tp = pt_tty[minor(dev)]; (*linesw[tp->t_line].l_close)(tp, flag); ttyclose(tp); ptcwakeup(tp, FREAD|FWRITE); + pt_ioctl[minor(dev)].pt_flags &= ~PF_SOPEN; + if ((pt_ioctl[minor(dev)].pt_flags & PF_COPEN) == 0) { + ttyfree(tp); + pt_tty[minor(dev)] = (struct tty *)NULL; + } return(0); } +int ptsread(dev, uio, flag) dev_t dev; struct uio *uio; + int flag; { struct proc *p = curproc; - register struct tty *tp = &pt_tty[minor(dev)]; + register struct tty *tp = pt_tty[minor(dev)]; register struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; int error = 0; @@ -171,22 +174,22 @@ again: TTIPRI | PCATCH, ttybg, 0)) return (error); } - if (RB_LEN(&tp->t_can) == 0) { + if (tp->t_canq.c_cc == 0) { if (flag & IO_NDELAY) return (EWOULDBLOCK); - if (error = ttysleep(tp, (caddr_t)&tp->t_can, + if (error = ttysleep(tp, (caddr_t)&tp->t_canq, TTIPRI | PCATCH, ttyin, 0)) return (error); goto again; } - while (RB_LEN(&tp->t_can) > 1 && uio->uio_resid > 0) - if (ureadc(getc(&tp->t_can), uio) < 0) { + while (tp->t_canq.c_cc > 1 && uio->uio_resid > 0) + if (ureadc(getc(&tp->t_canq), uio) < 0) { error = EFAULT; break; } - if (RB_LEN(&tp->t_can) == 1) - (void) getc(&tp->t_can); - if (RB_LEN(&tp->t_can)) + if (tp->t_canq.c_cc == 1) + (void) getc(&tp->t_canq); + if (tp->t_canq.c_cc) return (error); } else if (tp->t_oproc) @@ -200,13 +203,15 @@ again: * Wakeups of controlling tty will happen * indirectly, when tty driver calls ptsstart. */ +int ptswrite(dev, uio, flag) dev_t dev; struct uio *uio; + int flag; { register struct tty *tp; - tp = &pt_tty[minor(dev)]; + tp = pt_tty[minor(dev)]; if (tp->t_oproc == 0) return (EIO); return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); @@ -216,47 +221,45 @@ ptswrite(dev, uio, flag) * Start output on pseudo-tty. * Wake up process selecting or sleeping for input from controlling tty. */ +int ptsstart(tp) struct tty *tp; { register struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)]; if (tp->t_state & TS_TTSTOP) - return; + return 0; /* XXX should we return 1? */ if (pti->pt_flags & PF_STOPPED) { pti->pt_flags &= ~PF_STOPPED; pti->pt_send = TIOCPKT_START; } ptcwakeup(tp, FREAD); + return 0; } +void ptcwakeup(tp, flag) struct tty *tp; + int flag; { struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)]; if (flag & FREAD) { - if (pti->pt_selr) { - selwakeup(pti->pt_selr, pti->pt_flags & PF_RCOLL); - pti->pt_selr = 0; - pti->pt_flags &= ~PF_RCOLL; - } - wakeup((caddr_t)&tp->t_out.rb_tl); + selwakeup(&pti->pt_selr); + wakeup((caddr_t)&tp->t_outq.c_cl); } if (flag & FWRITE) { - if (pti->pt_selw) { - selwakeup(pti->pt_selw, pti->pt_flags & PF_WCOLL); - pti->pt_selw = 0; - pti->pt_flags &= ~PF_WCOLL; - } - wakeup((caddr_t)&tp->t_raw.rb_hd); + selwakeup(&pti->pt_selw); + wakeup((caddr_t)&tp->t_rawq.c_cf); } } /*ARGSUSED*/ #ifdef __STDC__ +int ptcopen(dev_t dev, int flag, int devtype, struct proc *p) #else +int ptcopen(dev, flag, devtype, p) dev_t dev; int flag, devtype; @@ -268,26 +271,32 @@ ptcopen(dev, flag, devtype, p) if (minor(dev) >= NPTY) return (ENXIO); - tp = &pt_tty[minor(dev)]; + if(!pt_tty[minor(dev)]) { + tp = pt_tty[minor(dev)] = ttymalloc(); + } else + tp = pt_tty[minor(dev)]; if (tp->t_oproc) return (EIO); tp->t_oproc = ptsstart; (void)(*linesw[tp->t_line].l_modem)(tp, 1); tp->t_lflag &= ~EXTPROC; pti = &pt_ioctl[minor(dev)]; - pti->pt_flags = 0; + pti->pt_flags &= PF_SOPEN; + pti->pt_flags |= PF_COPEN; pti->pt_send = 0; pti->pt_ucntl = 0; return (0); } extern struct tty *constty; /* -hv- 06.Oct.92*/ + +int ptcclose(dev) dev_t dev; { register struct tty *tp; - tp = &pt_tty[minor(dev)]; + tp = pt_tty[minor(dev)]; (void)(*linesw[tp->t_line].l_modem)(tp, 0); tp->t_state &= ~TS_CARR_ON; tp->t_oproc = 0; /* mark closed */ @@ -297,16 +306,23 @@ ptcclose(dev) if (constty==tp) constty = 0; + pt_ioctl[minor(dev)].pt_flags &= ~PF_COPEN; + if ((pt_ioctl[minor(dev)].pt_flags & PF_SOPEN) == 0) { + ttyfree(tp); + pt_tty[minor(dev)] = (struct tty *)NULL; + } return (0); } +int ptcread(dev, uio, flag) dev_t dev; struct uio *uio; + int flag; { - register struct tty *tp = &pt_tty[minor(dev)]; + register struct tty *tp = pt_tty[minor(dev)]; struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; - char buf[BUFSIZ]; + u_char buf[BUFSIZ]; int error = 0, cc; /* @@ -324,7 +340,8 @@ ptcread(dev, uio, flag) if (pti->pt_send & TIOCPKT_IOCTL) { cc = MIN(uio->uio_resid, sizeof(tp->t_termios)); - uiomove(&tp->t_termios, cc, uio); + uiomove((caddr_t)&tp->t_termios, cc, + uio); } pti->pt_send = 0; return (0); @@ -336,48 +353,36 @@ ptcread(dev, uio, flag) pti->pt_ucntl = 0; return (0); } - if (RB_LEN(&tp->t_out) && (tp->t_state&TS_TTSTOP) == 0) + if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) break; } if ((tp->t_state&TS_CARR_ON) == 0) return (0); /* EOF */ if (flag & IO_NDELAY) return (EWOULDBLOCK); - if (error = tsleep((caddr_t)&tp->t_out.rb_tl, TTIPRI | PCATCH, + if (error = tsleep((caddr_t)&tp->t_outq.c_cl, 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) { -#ifdef was cc = q_to_b(&tp->t_outq, buf, MIN(uio->uio_resid, BUFSIZ)); -#else - cc = min(MIN(uio->uio_resid, BUFSIZ), RB_CONTIGGET(&tp->t_out)); - if (cc) { - bcopy(tp->t_out.rb_hd, buf, cc); - tp->t_out.rb_hd = - RB_ROLLOVER(&tp->t_out, tp->t_out.rb_hd+cc); - } -#endif if (cc <= 0) break; error = uiomove(buf, cc, uio); } - if (RB_LEN(&tp->t_out) <= tp->t_lowat) { + 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_out); - } - if (tp->t_wsel) { - selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); - tp->t_wsel = 0; - tp->t_state &= ~TS_WCOLL; + wakeup((caddr_t)&tp->t_outq); } + selwakeup(&tp->t_wsel); } return (error); } +void ptsstop(tp, flush) register struct tty *tp; int flush; @@ -401,14 +406,14 @@ ptsstop(tp, flush) ptcwakeup(tp, flag); } +int ptcselect(dev, rw, p) dev_t dev; int rw; struct proc *p; { - register struct tty *tp = &pt_tty[minor(dev)]; + register struct tty *tp = pt_tty[minor(dev)]; struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; - struct proc *prev; int s; if ((tp->t_state&TS_CARR_ON) == 0) @@ -421,7 +426,7 @@ ptcselect(dev, rw, p) */ s = spltty(); if ((tp->t_state&TS_ISOPEN) && - RB_LEN(&tp->t_out) && (tp->t_state&TS_TTSTOP) == 0) { + tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) { splx(s); return (1); } @@ -433,40 +438,36 @@ ptcselect(dev, rw, p) (pti->pt_flags&PF_PKT && pti->pt_send || pti->pt_flags&PF_UCNTL && pti->pt_ucntl)) return (1); - if (pti->pt_selr && (prev = pfind(pti->pt_selr)) && prev->p_wchan == (caddr_t)&selwait) - pti->pt_flags |= PF_RCOLL; - else - pti->pt_selr = p->p_pid; + selrecord(p, &pti->pt_selr); break; case FWRITE: if (tp->t_state&TS_ISOPEN) { if (pti->pt_flags & PF_REMOTE) { - if (RB_LEN(&tp->t_can) == 0) + if (tp->t_canq.c_cc == 0) return (1); } else { - if (RB_LEN(&tp->t_raw) + RB_LEN(&tp->t_can) < TTYHOG-2) + if (tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG-2) return (1); - if (RB_LEN(&tp->t_can) == 0 && (tp->t_iflag&ICANON)) + if (tp->t_canq.c_cc == 0 && (tp->t_iflag&ICANON)) return (1); } } - if (pti->pt_selw && (prev = pfind(pti->pt_selw)) && prev->p_wchan == (caddr_t)&selwait) - pti->pt_flags |= PF_WCOLL; - else - pti->pt_selw = p->p_pid; + selrecord(p, &pti->pt_selw); break; } return (0); } +int ptcwrite(dev, uio, flag) dev_t dev; register struct uio *uio; + int flag; { - register struct tty *tp = &pt_tty[minor(dev)]; + register struct tty *tp = pt_tty[minor(dev)]; register u_char *cp; register int cc = 0; u_char locbuf[BUFSIZ]; @@ -478,12 +479,12 @@ again: if ((tp->t_state&TS_ISOPEN) == 0) goto block; if (pti->pt_flags & PF_REMOTE) { - if (RB_LEN(&tp->t_can)) + if (tp->t_canq.c_cc) goto block; - while (uio->uio_resid > 0 && RB_LEN(&tp->t_can) < TTYHOG - 1) { + 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 - RB_CONTIGPUT(&tp->t_can)); + cc = min(cc, TTYHOG - 1 - tp->t_canq.c_cc); cp = locbuf; error = uiomove((caddr_t)cp, cc, uio); if (error) @@ -492,21 +493,13 @@ again: if ((tp->t_state&TS_ISOPEN) == 0) return (EIO); } -#ifdef was if (cc) - (void) b_to_q((char *)cp, cc, &tp->t_canq); -#else - if (cc) { - bcopy(cp, tp->t_can.rb_tl, cc); - tp->t_can.rb_tl = - RB_ROLLOVER(&tp->t_can, tp->t_can.rb_tl+cc); - } -#endif + (void) b_to_q(cp, cc, &tp->t_canq); cc = 0; } - (void) putc(0, &tp->t_can); + (void) putc(0, &tp->t_canq); ttwakeup(tp); - wakeup((caddr_t)&tp->t_can); + wakeup((caddr_t)&tp->t_canq); return (0); } while (uio->uio_resid > 0) { @@ -521,9 +514,9 @@ again: return (EIO); } while (cc > 0) { - if ((RB_LEN(&tp->t_raw) + RB_LEN(&tp->t_can)) >= TTYHOG - 2 && - (RB_LEN(&tp->t_can) > 0 || !(tp->t_iflag&ICANON))) { - wakeup((caddr_t)&tp->t_raw); + 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); @@ -547,7 +540,7 @@ block: return (EWOULDBLOCK); return (0); } - if (error = tsleep((caddr_t)&tp->t_raw.rb_hd, TTOPRI | PCATCH, + 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; @@ -557,15 +550,16 @@ block: } /*ARGSUSED*/ +int ptyioctl(dev, cmd, data, flag) caddr_t data; + int cmd, flag; dev_t dev; { - register struct tty *tp = &pt_tty[minor(dev)]; + 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; - extern ttyinput(); /* * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG. @@ -639,8 +633,7 @@ ptyioctl(dev, cmd, data, flag) case TIOCSETA: case TIOCSETAW: case TIOCSETAF: - while (getc(&tp->t_out) >= 0) - ; + flushq(&tp->t_outq); break; case TIOCSIG: @@ -666,7 +659,7 @@ ptyioctl(dev, cmd, data, flag) if (linesw[tp->t_line].l_rint != ttyinput) { (*linesw[tp->t_line].l_close)(tp, flag); tp->t_line = TTYDISC; - (void)(*linesw[tp->t_line].l_open)(dev, tp, flag); + (void)(*linesw[tp->t_line].l_open)(dev, tp); error = ENOTTY; } if (error < 0) {