1*18651Sbloom /* tty_pty.c 6.10 85/04/17 */ 22283Stoy 32281Stoy /* 42281Stoy * Pseudo-teletype Driver 52281Stoy * (Actually two drivers, requiring two entries in 'cdevsw') 62281Stoy */ 72314Stoy #include "pty.h" 82314Stoy 93206Swnj #if NPTY > 0 1017096Sbloom #include "param.h" 1117096Sbloom #include "systm.h" 1217096Sbloom #include "ioctl.h" 1317096Sbloom #include "tty.h" 1417096Sbloom #include "dir.h" 1517096Sbloom #include "user.h" 1617096Sbloom #include "conf.h" 1717096Sbloom #include "file.h" 1817096Sbloom #include "proc.h" 1917096Sbloom #include "uio.h" 2017096Sbloom #include "kernel.h" 216239Sroot 227475Ssam #if NPTY == 1 23*18651Sbloom #undef NPTY 246239Sroot #define NPTY 32 /* crude XXX */ 257475Ssam #endif 262281Stoy 2716788Ssam #define BUFSIZ 100 /* Chunk size iomoved to/from user */ 284484Swnj 292281Stoy /* 30*18651Sbloom * pts == /dev/tty[pqrs]? 31*18651Sbloom * ptc == /dev/pty[pqrs]? 322281Stoy */ 334484Swnj struct tty pt_tty[NPTY]; 344484Swnj struct pt_ioctl { 355427Swnj int pt_flags; 365427Swnj int pt_gensym; 375427Swnj struct proc *pt_selr, *pt_selw; 38*18651Sbloom u_char pt_send; 39*18651Sbloom u_char pt_ucntl; 404484Swnj } pt_ioctl[NPTY]; 41*18651Sbloom int npty = NPTY; /* for pstat -t */ 422281Stoy 435427Swnj #define PF_RCOLL 0x01 445427Swnj #define PF_WCOLL 0x02 455427Swnj #define PF_NBIO 0x04 465427Swnj #define PF_PKT 0x08 /* packet mode */ 475574Swnj #define PF_STOPPED 0x10 /* user told stopped */ 485894Swnj #define PF_REMOTE 0x20 /* remote and flow controlled input */ 496119Swnj #define PF_NOSTOP 0x40 50*18651Sbloom #define PF_UCNTL 0x80 /* user control mode */ 512281Stoy 522281Stoy /*ARGSUSED*/ 532281Stoy ptsopen(dev, flag) 545396Sroot dev_t dev; 554484Swnj { 562281Stoy register struct tty *tp; 57*18651Sbloom int error; 582281Stoy 59*18651Sbloom #ifdef lint 60*18651Sbloom npty = npty; 61*18651Sbloom #endif 628563Sroot if (minor(dev) >= NPTY) 638563Sroot return (ENXIO); 642281Stoy tp = &pt_tty[minor(dev)]; 655408Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 662427Swnj ttychars(tp); /* Set up default chars */ 6712642Ssam tp->t_ispeed = tp->t_ospeed = EXTB; 682427Swnj tp->t_flags = 0; /* No features (nor raw mode) */ 698563Sroot } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) 708563Sroot return (EBUSY); 714484Swnj if (tp->t_oproc) /* Ctrlr still around. */ 725408Swnj tp->t_state |= TS_CARR_ON; 735408Swnj while ((tp->t_state & TS_CARR_ON) == 0) { 745408Swnj tp->t_state |= TS_WOPEN; 752281Stoy sleep((caddr_t)&tp->t_rawq, TTIPRI); 762281Stoy } 77*18651Sbloom error = (*linesw[tp->t_line].l_open)(dev, tp); 78*18651Sbloom ptcwakeup(tp, FREAD|FWRITE); 79*18651Sbloom return (error); 802281Stoy } 812281Stoy 822281Stoy ptsclose(dev) 835396Sroot dev_t dev; 845408Swnj { 852281Stoy register struct tty *tp; 862281Stoy 872281Stoy tp = &pt_tty[minor(dev)]; 882281Stoy (*linesw[tp->t_line].l_close)(tp); 896299Swnj ttyclose(tp); 90*18651Sbloom ptcwakeup(tp, FREAD|FWRITE); 912281Stoy } 922281Stoy 937823Sroot ptsread(dev, uio) 945396Sroot dev_t dev; 957823Sroot struct uio *uio; 964484Swnj { 975894Swnj register struct tty *tp = &pt_tty[minor(dev)]; 985894Swnj register struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; 998521Sroot int error = 0; 1002281Stoy 1015894Swnj again: 1025894Swnj if (pti->pt_flags & PF_REMOTE) { 1035894Swnj while (tp == u.u_ttyp && u.u_procp->p_pgrp != tp->t_pgrp) { 104*18651Sbloom if ((u.u_procp->p_sigignore & sigmask(SIGTTIN)) || 105*18651Sbloom (u.u_procp->p_sigmask & sigmask(SIGTTIN)) || 1065894Swnj /* 1075894Swnj (u.u_procp->p_flag&SDETACH) || 1085894Swnj */ 1095894Swnj u.u_procp->p_flag&SVFORK) 1108521Sroot return (EIO); 1115894Swnj gsignal(u.u_procp->p_pgrp, SIGTTIN); 1125894Swnj sleep((caddr_t)&lbolt, TTIPRI); 1135408Swnj } 114*18651Sbloom if (tp->t_canq.c_cc == 0) { 1158521Sroot if (tp->t_state & TS_NBIO) 1168521Sroot return (EWOULDBLOCK); 117*18651Sbloom sleep((caddr_t)&tp->t_canq, TTIPRI); 1185894Swnj goto again; 1195894Swnj } 120*18651Sbloom while (tp->t_canq.c_cc > 1 && uio->uio_resid > 0) 121*18651Sbloom if (ureadc(getc(&tp->t_canq), uio) < 0) { 1228521Sroot error = EFAULT; 1237823Sroot break; 1247823Sroot } 125*18651Sbloom if (tp->t_canq.c_cc == 1) 126*18651Sbloom (void) getc(&tp->t_canq); 127*18651Sbloom if (tp->t_canq.c_cc) 1288521Sroot return (error); 1295894Swnj } else 1305894Swnj if (tp->t_oproc) 1318521Sroot error = (*linesw[tp->t_line].l_read)(tp, uio); 132*18651Sbloom ptcwakeup(tp, FWRITE); 1338521Sroot return (error); 1342281Stoy } 1352281Stoy 1365408Swnj /* 1375408Swnj * Write to pseudo-tty. 1385408Swnj * Wakeups of controlling tty will happen 1395408Swnj * indirectly, when tty driver calls ptsstart. 1405408Swnj */ 1417823Sroot ptswrite(dev, uio) 1425396Sroot dev_t dev; 1437823Sroot struct uio *uio; 1444484Swnj { 1452281Stoy register struct tty *tp; 1462281Stoy 1472281Stoy tp = &pt_tty[minor(dev)]; 1488521Sroot if (tp->t_oproc == 0) 1498521Sroot return (EIO); 1508521Sroot return ((*linesw[tp->t_line].l_write)(tp, uio)); 1512281Stoy } 1522281Stoy 1535408Swnj /* 1545408Swnj * Start output on pseudo-tty. 1555408Swnj * Wake up process selecting or sleeping for input from controlling tty. 1565408Swnj */ 1572281Stoy ptsstart(tp) 1584484Swnj struct tty *tp; 1594484Swnj { 1605574Swnj register struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)]; 1614484Swnj 1625408Swnj if (tp->t_state & TS_TTSTOP) 1632281Stoy return; 1645574Swnj if (pti->pt_flags & PF_STOPPED) { 1655574Swnj pti->pt_flags &= ~PF_STOPPED; 1665574Swnj pti->pt_send = TIOCPKT_START; 1675574Swnj } 168*18651Sbloom ptcwakeup(tp, FREAD); 1695430Swnj } 1705430Swnj 171*18651Sbloom ptcwakeup(tp, flag) 1725430Swnj struct tty *tp; 1735430Swnj { 1745430Swnj struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)]; 1755430Swnj 176*18651Sbloom if (flag & FREAD) { 177*18651Sbloom if (pti->pt_selr) { 178*18651Sbloom selwakeup(pti->pt_selr, pti->pt_flags & PF_RCOLL); 179*18651Sbloom pti->pt_selr = 0; 180*18651Sbloom pti->pt_flags &= ~PF_RCOLL; 181*18651Sbloom } 182*18651Sbloom wakeup((caddr_t)&tp->t_outq.c_cf); 1834484Swnj } 184*18651Sbloom if (flag & FWRITE) { 185*18651Sbloom if (pti->pt_selw) { 186*18651Sbloom selwakeup(pti->pt_selw, pti->pt_flags & PF_WCOLL); 187*18651Sbloom pti->pt_selw = 0; 188*18651Sbloom pti->pt_flags &= ~PF_WCOLL; 189*18651Sbloom } 190*18651Sbloom wakeup((caddr_t)&tp->t_rawq.c_cf); 191*18651Sbloom } 1922281Stoy } 1932281Stoy 1942281Stoy /*ARGSUSED*/ 1952281Stoy ptcopen(dev, flag) 1964484Swnj dev_t dev; 1974484Swnj int flag; 1984484Swnj { 1992281Stoy register struct tty *tp; 2005427Swnj struct pt_ioctl *pti; 2012281Stoy 2028563Sroot if (minor(dev) >= NPTY) 2038563Sroot return (ENXIO); 2042281Stoy tp = &pt_tty[minor(dev)]; 2058563Sroot if (tp->t_oproc) 2068563Sroot return (EIO); 2074484Swnj tp->t_oproc = ptsstart; 2085408Swnj if (tp->t_state & TS_WOPEN) 2092281Stoy wakeup((caddr_t)&tp->t_rawq); 2105408Swnj tp->t_state |= TS_CARR_ON; 2115427Swnj pti = &pt_ioctl[minor(dev)]; 2125427Swnj pti->pt_flags = 0; 2135427Swnj pti->pt_send = 0; 214*18651Sbloom pti->pt_ucntl = 0; 2158563Sroot return (0); 2162281Stoy } 2172281Stoy 2182281Stoy ptcclose(dev) 2194484Swnj dev_t dev; 2204484Swnj { 2212281Stoy register struct tty *tp; 2222281Stoy 2232281Stoy tp = &pt_tty[minor(dev)]; 2245408Swnj if (tp->t_state & TS_ISOPEN) 2252281Stoy gsignal(tp->t_pgrp, SIGHUP); 2265408Swnj tp->t_state &= ~TS_CARR_ON; /* virtual carrier gone */ 22712753Ssam ttyflush(tp, FREAD|FWRITE); 2284484Swnj tp->t_oproc = 0; /* mark closed */ 2292281Stoy } 2302281Stoy 2317823Sroot ptcread(dev, uio) 2325427Swnj dev_t dev; 2337823Sroot struct uio *uio; 2344484Swnj { 2358521Sroot register struct tty *tp = &pt_tty[minor(dev)]; 236*18651Sbloom struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; 23716788Ssam char buf[BUFSIZ]; 23816788Ssam int error = 0, cc; 2392281Stoy 240*18651Sbloom /* 241*18651Sbloom * We want to block until the slave 242*18651Sbloom * is open, and there's something to read; 243*18651Sbloom * but if we lost the slave or we're NBIO, 244*18651Sbloom * then return the appropriate error instead. 245*18651Sbloom */ 246*18651Sbloom for (;;) { 247*18651Sbloom if (tp->t_state&TS_ISOPEN) { 248*18651Sbloom if (pti->pt_flags&PF_PKT && pti->pt_send) { 249*18651Sbloom error = ureadc(pti->pt_send, uio); 250*18651Sbloom if (error) 251*18651Sbloom return (error); 252*18651Sbloom pti->pt_send = 0; 253*18651Sbloom return (0); 254*18651Sbloom } 255*18651Sbloom if (pti->pt_flags&PF_UCNTL && pti->pt_ucntl) { 256*18651Sbloom error = ureadc(pti->pt_ucntl, uio); 257*18651Sbloom if (error) 258*18651Sbloom return (error); 259*18651Sbloom pti->pt_ucntl = 0; 260*18651Sbloom return (0); 261*18651Sbloom } 262*18651Sbloom if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) 263*18651Sbloom break; 2645427Swnj } 26516788Ssam if ((tp->t_state&TS_CARR_ON) == 0) 26616788Ssam return (EIO); 2678521Sroot if (pti->pt_flags&PF_NBIO) 2688521Sroot return (EWOULDBLOCK); 2692281Stoy sleep((caddr_t)&tp->t_outq.c_cf, TTIPRI); 2705411Swnj } 271*18651Sbloom if (pti->pt_flags & (PF_PKT|PF_UCNTL)) 272*18651Sbloom error = ureadc(0, uio); 27316788Ssam while (uio->uio_resid > 0 && error == 0) { 27416788Ssam cc = q_to_b(&tp->t_outq, buf, MIN(uio->uio_resid, BUFSIZ)); 27516788Ssam if (cc <= 0) 2767823Sroot break; 27716788Ssam error = uiomove(buf, cc, UIO_READ, uio); 27816788Ssam } 2795408Swnj if (tp->t_outq.c_cc <= TTLOWAT(tp)) { 2805408Swnj if (tp->t_state&TS_ASLEEP) { 2815408Swnj tp->t_state &= ~TS_ASLEEP; 2825408Swnj wakeup((caddr_t)&tp->t_outq); 2835408Swnj } 2845408Swnj if (tp->t_wsel) { 2855408Swnj selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 2865408Swnj tp->t_wsel = 0; 2875408Swnj tp->t_state &= ~TS_WCOLL; 2885408Swnj } 2892281Stoy } 2908521Sroot return (error); 2912281Stoy } 2922281Stoy 2935427Swnj ptsstop(tp, flush) 2945427Swnj register struct tty *tp; 2955427Swnj int flush; 2965427Swnj { 2975427Swnj struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)]; 298*18651Sbloom int flag; 2995427Swnj 3005574Swnj /* note: FLUSHREAD and FLUSHWRITE already ok */ 3015574Swnj if (flush == 0) { 3025574Swnj flush = TIOCPKT_STOP; 3035574Swnj pti->pt_flags |= PF_STOPPED; 304*18651Sbloom } else 3055574Swnj pti->pt_flags &= ~PF_STOPPED; 3066119Swnj pti->pt_send |= flush; 307*18651Sbloom /* change of perspective */ 308*18651Sbloom flag = 0; 309*18651Sbloom if (flush & FREAD) 310*18651Sbloom flag |= FWRITE; 311*18651Sbloom if (flush & FWRITE) 312*18651Sbloom flag |= FREAD; 313*18651Sbloom ptcwakeup(tp, flush); 3145427Swnj } 3155427Swnj 3165408Swnj ptcselect(dev, rw) 3174484Swnj dev_t dev; 3185408Swnj int rw; 3194484Swnj { 3204484Swnj register struct tty *tp = &pt_tty[minor(dev)]; 3215894Swnj struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; 3224484Swnj struct proc *p; 3235430Swnj int s; 3244484Swnj 325*18651Sbloom if ((tp->t_state&TS_CARR_ON) == 0) 3264484Swnj return (1); 3275430Swnj s = spl5(); 3285408Swnj switch (rw) { 3295408Swnj 3305408Swnj case FREAD: 331*18651Sbloom if ((tp->t_state&TS_ISOPEN) && 332*18651Sbloom (pti->pt_flags&PF_PKT && pti->pt_send || 333*18651Sbloom pti->pt_flags&PF_UCNTL && pti->pt_ucntl || 334*18651Sbloom tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)) { 3355430Swnj splx(s); 3365408Swnj return (1); 3375430Swnj } 3385427Swnj if ((p = pti->pt_selr) && p->p_wchan == (caddr_t)&selwait) 3395427Swnj pti->pt_flags |= PF_RCOLL; 3405408Swnj else 3415427Swnj pti->pt_selr = u.u_procp; 3425430Swnj break; 3435408Swnj 3445408Swnj case FWRITE: 345*18651Sbloom if ((tp->t_state&TS_ISOPEN) && 346*18651Sbloom (((pti->pt_flags&PF_REMOTE) && tp->t_canq.c_cc) || 347*18651Sbloom (tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG - 2))) { 3485430Swnj splx(s); 3495408Swnj return (1); 3505430Swnj } 3515427Swnj if ((p = pti->pt_selw) && p->p_wchan == (caddr_t)&selwait) 3525427Swnj pti->pt_flags |= PF_WCOLL; 3535408Swnj else 3545427Swnj pti->pt_selw = u.u_procp; 3555430Swnj break; 3565408Swnj } 3575430Swnj splx(s); 3585430Swnj return (0); 3595396Sroot } 3604484Swnj 3617823Sroot ptcwrite(dev, uio) 3625408Swnj dev_t dev; 363*18651Sbloom register struct uio *uio; 3644484Swnj { 3658521Sroot register struct tty *tp = &pt_tty[minor(dev)]; 366*18651Sbloom register struct iovec *iov; 367*18651Sbloom register char *cp; 368*18651Sbloom register int cc = 0; 3692281Stoy char locbuf[BUFSIZ]; 3705408Swnj int cnt = 0; 3715894Swnj struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; 3728521Sroot int error = 0; 3732281Stoy 374*18651Sbloom again: 375*18651Sbloom if ((tp->t_state&TS_ISOPEN) == 0) 376*18651Sbloom goto block; 377*18651Sbloom if (cnt == 0 && pti->pt_flags & PF_REMOTE) { 378*18651Sbloom if (uio->uio_iovcnt <= 0) 379*18651Sbloom return (0); 380*18651Sbloom if (tp->t_canq.c_cc) 381*18651Sbloom goto block; 3827823Sroot iov = uio->uio_iov; 383*18651Sbloom if (cc == 0 && iov->iov_len) { 384*18651Sbloom cc = MIN(iov->iov_len, BUFSIZ); 385*18651Sbloom cp = locbuf; 386*18651Sbloom error = uiomove(cp, cc, UIO_WRITE, uio); 387*18651Sbloom if (error) 388*18651Sbloom return (error); 389*18651Sbloom /* check again for safety */ 390*18651Sbloom if ((tp->t_state&TS_ISOPEN) == 0) 391*18651Sbloom return (EIO); 392*18651Sbloom if (tp->t_canq.c_cc) 393*18651Sbloom goto block; 3947823Sroot } 395*18651Sbloom if (cc) 396*18651Sbloom (void) b_to_q(cp, cc, &tp->t_canq); 397*18651Sbloom (void) putc(0, &tp->t_canq); 398*18651Sbloom ttwakeup(tp); 399*18651Sbloom wakeup((caddr_t)&tp->t_canq); 400*18651Sbloom return (0); 401*18651Sbloom } 402*18651Sbloom while (uio->uio_iovcnt > 0) { 403*18651Sbloom iov = uio->uio_iov; 404*18651Sbloom if (cc == 0) { 405*18651Sbloom if (iov->iov_len == 0) { 406*18651Sbloom uio->uio_iovcnt--; 407*18651Sbloom uio->uio_iov++; 408*18651Sbloom continue; 4095894Swnj } 410*18651Sbloom cc = MIN(iov->iov_len, BUFSIZ); 411*18651Sbloom cp = locbuf; 412*18651Sbloom error = uiomove(cp, cc, UIO_WRITE, uio); 413*18651Sbloom if (error) 414*18651Sbloom return (error); 415*18651Sbloom /* check again for safety */ 416*18651Sbloom if ((tp->t_state&TS_ISOPEN) == 0) 417*18651Sbloom return (EIO); 4185894Swnj } 419*18651Sbloom while (--cc >= 0) { 4204141Secc (*linesw[tp->t_line].l_rint)(*cp++, tp); 4215408Swnj cnt++; 4222281Stoy } 423*18651Sbloom cc = 0; 424*18651Sbloom } 425*18651Sbloom return (0); 426*18651Sbloom block: 427*18651Sbloom /* 428*18651Sbloom * Come here to wait for slave to open or for space 429*18651Sbloom * in outq. 430*18651Sbloom */ 431*18651Sbloom if ((tp->t_state&TS_CARR_ON) == 0) 432*18651Sbloom return (EIO); 433*18651Sbloom if (pti->pt_flags & PF_NBIO) { 434*18651Sbloom if (cnt == 0) 435*18651Sbloom return (EWOULDBLOCK); 436*18651Sbloom iov->iov_base -= cc; 437*18651Sbloom iov->iov_len += cc; 438*18651Sbloom uio->uio_resid += cc; 439*18651Sbloom uio->uio_offset -= cc; 440*18651Sbloom return (0); 441*18651Sbloom } 442*18651Sbloom sleep((caddr_t)&tp->t_rawq.c_cf, TTOPRI); 443*18651Sbloom goto again; 4442281Stoy } 4452281Stoy 4462281Stoy /*ARGSUSED*/ 4477626Ssam ptyioctl(dev, cmd, data, flag) 4487626Ssam caddr_t data; 4494484Swnj dev_t dev; 4504484Swnj { 4516119Swnj register struct tty *tp = &pt_tty[minor(dev)]; 4526119Swnj register struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; 453*18651Sbloom int stop, error; 4542281Stoy 4554484Swnj /* IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG ??? */ 4567626Ssam if (cdevsw[major(dev)].d_open == ptcopen) 4577626Ssam switch (cmd) { 4587626Ssam 4597626Ssam case TIOCPKT: 460*18651Sbloom if (*(int *)data) { 461*18651Sbloom if (pti->pt_flags & PF_UCNTL) 462*18651Sbloom return (EINVAL); 4635427Swnj pti->pt_flags |= PF_PKT; 464*18651Sbloom } else 4655427Swnj pti->pt_flags &= ~PF_PKT; 4668563Sroot return (0); 4677626Ssam 468*18651Sbloom case TIOCUCNTL: 469*18651Sbloom if (*(int *)data) { 470*18651Sbloom if (pti->pt_flags & PF_PKT) 471*18651Sbloom return (EINVAL); 472*18651Sbloom pti->pt_flags |= PF_UCNTL; 473*18651Sbloom } else 474*18651Sbloom pti->pt_flags &= ~PF_UCNTL; 475*18651Sbloom return (0); 476*18651Sbloom 4777626Ssam case TIOCREMOTE: 4787626Ssam if (*(int *)data) 4795894Swnj pti->pt_flags |= PF_REMOTE; 4805894Swnj else 4815894Swnj pti->pt_flags &= ~PF_REMOTE; 48212753Ssam ttyflush(tp, FREAD|FWRITE); 4838563Sroot return (0); 4847626Ssam 4857626Ssam case FIONBIO: 4867626Ssam if (*(int *)data) 4875427Swnj pti->pt_flags |= PF_NBIO; 4885411Swnj else 4895427Swnj pti->pt_flags &= ~PF_NBIO; 4908563Sroot return (0); 4917626Ssam 4927626Ssam case TIOCSETP: 4937626Ssam while (getc(&tp->t_outq) >= 0) 4947626Ssam ; 4957626Ssam break; 4965411Swnj } 49717182Smckusick error = ttioctl(tp, cmd, data, flag); 498*18651Sbloom if (error < 0) { 499*18651Sbloom if (pti->pt_flags & PF_UCNTL && 500*18651Sbloom (cmd & ~0xff) == _IO(u,0)) { 501*18651Sbloom if (cmd & 0xff) { 502*18651Sbloom pti->pt_ucntl = (u_char)cmd; 503*18651Sbloom ptcwakeup(tp, FREAD); 504*18651Sbloom } 505*18651Sbloom return (0); 506*18651Sbloom } 5078563Sroot error = ENOTTY; 508*18651Sbloom } 509*18651Sbloom stop = (tp->t_flags & RAW) == 0 && 510*18651Sbloom tp->t_stopc == CTRL(s) && tp->t_startc == CTRL(q); 5116119Swnj if (pti->pt_flags & PF_NOSTOP) { 5126119Swnj if (stop) { 5136119Swnj pti->pt_send &= TIOCPKT_NOSTOP; 5146119Swnj pti->pt_send |= TIOCPKT_DOSTOP; 5156119Swnj pti->pt_flags &= ~PF_NOSTOP; 516*18651Sbloom ptcwakeup(tp, FREAD); 5176119Swnj } 5186119Swnj } else { 519*18651Sbloom if (!stop) { 5206119Swnj pti->pt_send &= ~TIOCPKT_DOSTOP; 5216119Swnj pti->pt_send |= TIOCPKT_NOSTOP; 5226119Swnj pti->pt_flags |= PF_NOSTOP; 523*18651Sbloom ptcwakeup(tp, FREAD); 5246119Swnj } 5256119Swnj } 5268563Sroot return (error); 5272281Stoy } 5282313Stoy #endif 529