1*22731Skarels /* tty_pty.c 6.11 85/06/07 */ 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 2318651Sbloom #undef NPTY 246239Sroot #define NPTY 32 /* crude XXX */ 257475Ssam #endif 262281Stoy 2716788Ssam #define BUFSIZ 100 /* Chunk size iomoved to/from user */ 284484Swnj 292281Stoy /* 3018651Sbloom * pts == /dev/tty[pqrs]? 3118651Sbloom * 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; 3818651Sbloom u_char pt_send; 3918651Sbloom u_char pt_ucntl; 404484Swnj } pt_ioctl[NPTY]; 4118651Sbloom 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 5018651Sbloom #define PF_UCNTL 0x80 /* user control mode */ 512281Stoy 522281Stoy /*ARGSUSED*/ 532281Stoy ptsopen(dev, flag) 545396Sroot dev_t dev; 554484Swnj { 562281Stoy register struct tty *tp; 5718651Sbloom int error; 582281Stoy 5918651Sbloom #ifdef lint 6018651Sbloom npty = npty; 6118651Sbloom #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 } 7718651Sbloom error = (*linesw[tp->t_line].l_open)(dev, tp); 7818651Sbloom ptcwakeup(tp, FREAD|FWRITE); 7918651Sbloom 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); 9018651Sbloom 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) { 10418651Sbloom if ((u.u_procp->p_sigignore & sigmask(SIGTTIN)) || 10518651Sbloom (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 } 11418651Sbloom if (tp->t_canq.c_cc == 0) { 1158521Sroot if (tp->t_state & TS_NBIO) 1168521Sroot return (EWOULDBLOCK); 11718651Sbloom sleep((caddr_t)&tp->t_canq, TTIPRI); 1185894Swnj goto again; 1195894Swnj } 12018651Sbloom while (tp->t_canq.c_cc > 1 && uio->uio_resid > 0) 12118651Sbloom if (ureadc(getc(&tp->t_canq), uio) < 0) { 1228521Sroot error = EFAULT; 1237823Sroot break; 1247823Sroot } 12518651Sbloom if (tp->t_canq.c_cc == 1) 12618651Sbloom (void) getc(&tp->t_canq); 12718651Sbloom 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); 13218651Sbloom 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 } 16818651Sbloom ptcwakeup(tp, FREAD); 1695430Swnj } 1705430Swnj 17118651Sbloom ptcwakeup(tp, flag) 1725430Swnj struct tty *tp; 1735430Swnj { 1745430Swnj struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)]; 1755430Swnj 17618651Sbloom if (flag & FREAD) { 17718651Sbloom if (pti->pt_selr) { 17818651Sbloom selwakeup(pti->pt_selr, pti->pt_flags & PF_RCOLL); 17918651Sbloom pti->pt_selr = 0; 18018651Sbloom pti->pt_flags &= ~PF_RCOLL; 18118651Sbloom } 18218651Sbloom wakeup((caddr_t)&tp->t_outq.c_cf); 1834484Swnj } 18418651Sbloom if (flag & FWRITE) { 18518651Sbloom if (pti->pt_selw) { 18618651Sbloom selwakeup(pti->pt_selw, pti->pt_flags & PF_WCOLL); 18718651Sbloom pti->pt_selw = 0; 18818651Sbloom pti->pt_flags &= ~PF_WCOLL; 18918651Sbloom } 19018651Sbloom wakeup((caddr_t)&tp->t_rawq.c_cf); 19118651Sbloom } 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; 21418651Sbloom 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)]; 23618651Sbloom struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; 23716788Ssam char buf[BUFSIZ]; 23816788Ssam int error = 0, cc; 2392281Stoy 24018651Sbloom /* 24118651Sbloom * We want to block until the slave 24218651Sbloom * is open, and there's something to read; 24318651Sbloom * but if we lost the slave or we're NBIO, 24418651Sbloom * then return the appropriate error instead. 24518651Sbloom */ 24618651Sbloom for (;;) { 24718651Sbloom if (tp->t_state&TS_ISOPEN) { 24818651Sbloom if (pti->pt_flags&PF_PKT && pti->pt_send) { 24918651Sbloom error = ureadc(pti->pt_send, uio); 25018651Sbloom if (error) 25118651Sbloom return (error); 25218651Sbloom pti->pt_send = 0; 25318651Sbloom return (0); 25418651Sbloom } 25518651Sbloom if (pti->pt_flags&PF_UCNTL && pti->pt_ucntl) { 25618651Sbloom error = ureadc(pti->pt_ucntl, uio); 25718651Sbloom if (error) 25818651Sbloom return (error); 25918651Sbloom pti->pt_ucntl = 0; 26018651Sbloom return (0); 26118651Sbloom } 26218651Sbloom if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) 26318651Sbloom 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 } 27118651Sbloom if (pti->pt_flags & (PF_PKT|PF_UCNTL)) 27218651Sbloom 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)]; 29818651Sbloom int flag; 2995427Swnj 3005574Swnj /* note: FLUSHREAD and FLUSHWRITE already ok */ 3015574Swnj if (flush == 0) { 3025574Swnj flush = TIOCPKT_STOP; 3035574Swnj pti->pt_flags |= PF_STOPPED; 30418651Sbloom } else 3055574Swnj pti->pt_flags &= ~PF_STOPPED; 3066119Swnj pti->pt_send |= flush; 30718651Sbloom /* change of perspective */ 30818651Sbloom flag = 0; 30918651Sbloom if (flush & FREAD) 31018651Sbloom flag |= FWRITE; 31118651Sbloom if (flush & FWRITE) 31218651Sbloom flag |= FREAD; 31318651Sbloom 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 32518651Sbloom if ((tp->t_state&TS_CARR_ON) == 0) 3264484Swnj return (1); 3275430Swnj s = spl5(); 3285408Swnj switch (rw) { 3295408Swnj 3305408Swnj case FREAD: 33118651Sbloom if ((tp->t_state&TS_ISOPEN) && 33218651Sbloom (pti->pt_flags&PF_PKT && pti->pt_send || 33318651Sbloom pti->pt_flags&PF_UCNTL && pti->pt_ucntl || 33418651Sbloom 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: 34518651Sbloom if ((tp->t_state&TS_ISOPEN) && 346*22731Skarels ((pti->pt_flags&PF_REMOTE) == 0 || tp->t_canq.c_cc == 0)) { 3475430Swnj splx(s); 3485408Swnj return (1); 3495430Swnj } 3505427Swnj if ((p = pti->pt_selw) && p->p_wchan == (caddr_t)&selwait) 3515427Swnj pti->pt_flags |= PF_WCOLL; 3525408Swnj else 3535427Swnj pti->pt_selw = u.u_procp; 3545430Swnj break; 3555408Swnj } 3565430Swnj splx(s); 3575430Swnj return (0); 3585396Sroot } 3594484Swnj 3607823Sroot ptcwrite(dev, uio) 3615408Swnj dev_t dev; 36218651Sbloom register struct uio *uio; 3634484Swnj { 3648521Sroot register struct tty *tp = &pt_tty[minor(dev)]; 36518651Sbloom register struct iovec *iov; 36618651Sbloom register char *cp; 36718651Sbloom register int cc = 0; 3682281Stoy char locbuf[BUFSIZ]; 3695408Swnj int cnt = 0; 3705894Swnj struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; 3718521Sroot int error = 0; 3722281Stoy 37318651Sbloom again: 37418651Sbloom if ((tp->t_state&TS_ISOPEN) == 0) 37518651Sbloom goto block; 37618651Sbloom if (cnt == 0 && pti->pt_flags & PF_REMOTE) { 37718651Sbloom if (uio->uio_iovcnt <= 0) 37818651Sbloom return (0); 37918651Sbloom if (tp->t_canq.c_cc) 38018651Sbloom goto block; 3817823Sroot iov = uio->uio_iov; 38218651Sbloom if (cc == 0 && iov->iov_len) { 38318651Sbloom cc = MIN(iov->iov_len, BUFSIZ); 38418651Sbloom cp = locbuf; 38518651Sbloom error = uiomove(cp, cc, UIO_WRITE, uio); 38618651Sbloom if (error) 38718651Sbloom return (error); 38818651Sbloom /* check again for safety */ 38918651Sbloom if ((tp->t_state&TS_ISOPEN) == 0) 39018651Sbloom return (EIO); 39118651Sbloom if (tp->t_canq.c_cc) 39218651Sbloom goto block; 3937823Sroot } 39418651Sbloom if (cc) 39518651Sbloom (void) b_to_q(cp, cc, &tp->t_canq); 39618651Sbloom (void) putc(0, &tp->t_canq); 39718651Sbloom ttwakeup(tp); 39818651Sbloom wakeup((caddr_t)&tp->t_canq); 39918651Sbloom return (0); 40018651Sbloom } 40118651Sbloom while (uio->uio_iovcnt > 0) { 40218651Sbloom iov = uio->uio_iov; 40318651Sbloom if (cc == 0) { 40418651Sbloom if (iov->iov_len == 0) { 40518651Sbloom uio->uio_iovcnt--; 40618651Sbloom uio->uio_iov++; 40718651Sbloom continue; 4085894Swnj } 40918651Sbloom cc = MIN(iov->iov_len, BUFSIZ); 41018651Sbloom cp = locbuf; 41118651Sbloom error = uiomove(cp, cc, UIO_WRITE, uio); 41218651Sbloom if (error) 41318651Sbloom return (error); 41418651Sbloom /* check again for safety */ 41518651Sbloom if ((tp->t_state&TS_ISOPEN) == 0) 41618651Sbloom return (EIO); 4175894Swnj } 41818651Sbloom while (--cc >= 0) { 4194141Secc (*linesw[tp->t_line].l_rint)(*cp++, tp); 4205408Swnj cnt++; 4212281Stoy } 42218651Sbloom cc = 0; 42318651Sbloom } 42418651Sbloom return (0); 42518651Sbloom block: 42618651Sbloom /* 42718651Sbloom * Come here to wait for slave to open or for space 42818651Sbloom * in outq. 42918651Sbloom */ 43018651Sbloom if ((tp->t_state&TS_CARR_ON) == 0) 43118651Sbloom return (EIO); 43218651Sbloom if (pti->pt_flags & PF_NBIO) { 43318651Sbloom if (cnt == 0) 43418651Sbloom return (EWOULDBLOCK); 43518651Sbloom iov->iov_base -= cc; 43618651Sbloom iov->iov_len += cc; 43718651Sbloom uio->uio_resid += cc; 43818651Sbloom uio->uio_offset -= cc; 43918651Sbloom return (0); 44018651Sbloom } 44118651Sbloom sleep((caddr_t)&tp->t_rawq.c_cf, TTOPRI); 44218651Sbloom goto again; 4432281Stoy } 4442281Stoy 4452281Stoy /*ARGSUSED*/ 4467626Ssam ptyioctl(dev, cmd, data, flag) 4477626Ssam caddr_t data; 4484484Swnj dev_t dev; 4494484Swnj { 4506119Swnj register struct tty *tp = &pt_tty[minor(dev)]; 4516119Swnj register struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; 45218651Sbloom int stop, error; 4532281Stoy 4544484Swnj /* IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG ??? */ 4557626Ssam if (cdevsw[major(dev)].d_open == ptcopen) 4567626Ssam switch (cmd) { 4577626Ssam 4587626Ssam case TIOCPKT: 45918651Sbloom if (*(int *)data) { 46018651Sbloom if (pti->pt_flags & PF_UCNTL) 46118651Sbloom return (EINVAL); 4625427Swnj pti->pt_flags |= PF_PKT; 46318651Sbloom } else 4645427Swnj pti->pt_flags &= ~PF_PKT; 4658563Sroot return (0); 4667626Ssam 46718651Sbloom case TIOCUCNTL: 46818651Sbloom if (*(int *)data) { 46918651Sbloom if (pti->pt_flags & PF_PKT) 47018651Sbloom return (EINVAL); 47118651Sbloom pti->pt_flags |= PF_UCNTL; 47218651Sbloom } else 47318651Sbloom pti->pt_flags &= ~PF_UCNTL; 47418651Sbloom return (0); 47518651Sbloom 4767626Ssam case TIOCREMOTE: 4777626Ssam if (*(int *)data) 4785894Swnj pti->pt_flags |= PF_REMOTE; 4795894Swnj else 4805894Swnj pti->pt_flags &= ~PF_REMOTE; 48112753Ssam ttyflush(tp, FREAD|FWRITE); 4828563Sroot return (0); 4837626Ssam 4847626Ssam case FIONBIO: 4857626Ssam if (*(int *)data) 4865427Swnj pti->pt_flags |= PF_NBIO; 4875411Swnj else 4885427Swnj pti->pt_flags &= ~PF_NBIO; 4898563Sroot return (0); 4907626Ssam 4917626Ssam case TIOCSETP: 4927626Ssam while (getc(&tp->t_outq) >= 0) 4937626Ssam ; 4947626Ssam break; 4955411Swnj } 49617182Smckusick error = ttioctl(tp, cmd, data, flag); 49718651Sbloom if (error < 0) { 49818651Sbloom if (pti->pt_flags & PF_UCNTL && 49918651Sbloom (cmd & ~0xff) == _IO(u,0)) { 50018651Sbloom if (cmd & 0xff) { 50118651Sbloom pti->pt_ucntl = (u_char)cmd; 50218651Sbloom ptcwakeup(tp, FREAD); 50318651Sbloom } 50418651Sbloom return (0); 50518651Sbloom } 5068563Sroot error = ENOTTY; 50718651Sbloom } 50818651Sbloom stop = (tp->t_flags & RAW) == 0 && 50918651Sbloom tp->t_stopc == CTRL(s) && tp->t_startc == CTRL(q); 5106119Swnj if (pti->pt_flags & PF_NOSTOP) { 5116119Swnj if (stop) { 5126119Swnj pti->pt_send &= TIOCPKT_NOSTOP; 5136119Swnj pti->pt_send |= TIOCPKT_DOSTOP; 5146119Swnj pti->pt_flags &= ~PF_NOSTOP; 51518651Sbloom ptcwakeup(tp, FREAD); 5166119Swnj } 5176119Swnj } else { 51818651Sbloom if (!stop) { 5196119Swnj pti->pt_send &= ~TIOCPKT_DOSTOP; 5206119Swnj pti->pt_send |= TIOCPKT_NOSTOP; 5216119Swnj pti->pt_flags |= PF_NOSTOP; 52218651Sbloom ptcwakeup(tp, FREAD); 5236119Swnj } 5246119Swnj } 5258563Sroot return (error); 5262281Stoy } 5272313Stoy #endif 528