X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/8c8a5b54e79564c14fc7a2823a21a8f048449bcf..af359dea2e5ab3e937b62107ecd6a51d78189ed7:/usr/src/sys/kern/tty_pty.c diff --git a/usr/src/sys/kern/tty_pty.c b/usr/src/sys/kern/tty_pty.c index 5a0a0a634d..eb9bf5fe9c 100644 --- a/usr/src/sys/kern/tty_pty.c +++ b/usr/src/sys/kern/tty_pty.c @@ -2,9 +2,35 @@ * Copyright (c) 1982, 1986, 1989 The Regents of the University of California. * All rights reserved. * - * %sccs.include.redist.c% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * @(#)tty_pty.c 7.18 (Berkeley) %G% + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * 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 */ /* @@ -18,14 +44,12 @@ #include "systm.h" #include "ioctl.h" #include "tty.h" -#include "user.h" #include "conf.h" #include "file.h" #include "proc.h" #include "uio.h" #include "kernel.h" #include "vnode.h" -#include "tsleep.h" #if NPTY == 1 #undef NPTY @@ -44,31 +68,22 @@ struct pt_ioctl { struct proc *pt_selr, *pt_selw; u_char pt_send; u_char pt_ucntl; - struct clist pt_ioc; } pt_ioctl[NPTY]; int npty = NPTY; /* for pstat -t */ -int ptydebug = 0; - -#define PF_RCOLL 0x0001 -#define PF_WCOLL 0x0002 -#define PF_NBIO 0x0004 -#define PF_PKT 0x0008 /* packet mode */ -#define PF_STOPPED 0x0010 /* user told stopped */ -#define PF_REMOTE 0x0020 /* remote and flow controlled input */ -#define PF_NOSTOP 0x0040 -#define PF_UCNTL 0x0080 /* user control mode */ -#define PF_TIOC 0x0100 /* transparent control mode */ -#define PF_LIOC 0x0200 /* transparent control locked */ -#define PF_WIOC 0x0400 /* waiting for PF_LIOC to clear */ -#define PF_BLOCK 0x0800 /* block writes to slave */ -#define PF_OWAIT 0x1000 /* waiting for PF_BLOCK to clear */ +#define PF_RCOLL 0x01 +#define PF_WCOLL 0x02 +#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 */ /*ARGSUSED*/ -ptsopen(dev, flag) +ptsopen(dev, flag, devtype, p) dev_t dev; + struct proc *p; { - struct proc *p = curproc; register struct tty *tp; int error; @@ -93,7 +108,7 @@ ptsopen(dev, flag) tp->t_state |= TS_CARR_ON; while ((tp->t_state & TS_CARR_ON) == 0) { tp->t_state |= TS_WOPEN; - if (flag&FNDELAY) + if (flag&FNONBLOCK) break; if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, ttopen, 0)) @@ -104,16 +119,17 @@ ptsopen(dev, flag) return (error); } -ptsclose(dev) +ptsclose(dev, flag, mode, p) dev_t dev; + int flag, mode; + struct proc *p; { register struct tty *tp; tp = &pt_tty[minor(dev)]; - (*linesw[tp->t_line].l_close)(tp); + (*linesw[tp->t_line].l_close)(tp, flag); ttyclose(tp); ptcwakeup(tp, FREAD|FWRITE); - return (0); } ptsread(dev, uio, flag) @@ -171,17 +187,11 @@ ptswrite(dev, uio, flag) dev_t dev; struct uio *uio; { - register struct tty *tp = &pt_tty[minor(dev)]; - register struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; + register struct tty *tp; + tp = &pt_tty[minor(dev)]; if (tp->t_oproc == 0) return (EIO); - - while (pti->pt_flags & PF_BLOCK) { - pti->pt_flags |= PF_OWAIT; - sleep((caddr_t)pti + 1, TTOPRI); - } - return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); } @@ -222,15 +232,19 @@ ptcwakeup(tp, flag) pti->pt_selw = 0; pti->pt_flags &= ~PF_WCOLL; } -if (ptydebug) printf("WAKEUP c_cf %d\n", curproc->p_pid); wakeup((caddr_t)&tp->t_rawq.c_cf); } } /*ARGSUSED*/ -ptcopen(dev, flag) +#ifdef __STDC__ +ptcopen(dev_t dev, int flag, int devtype, struct proc *p) +#else +ptcopen(dev, flag, devtype, p) dev_t dev; - int flag; + int flag, devtype; + struct proc *p; +#endif { register struct tty *tp; struct pt_ioctl *pti; @@ -260,7 +274,6 @@ ptcclose(dev) tp->t_state &= ~TS_CARR_ON; tp->t_oproc = 0; /* mark closed */ tp->t_session = 0; - return (0); } ptcread(dev, uio, flag) @@ -299,19 +312,6 @@ ptcread(dev, uio, flag) pti->pt_ucntl = 0; return (0); } - if (pti->pt_flags&PF_TIOC && pti->pt_ioc.c_cc) { - if (uio->uio_resid < pti->pt_ioc.c_cc + 1) - return (E2BIG); - error = ureadc(TIOCPKT_TIOC, uio); - while (error == 0 && pti->pt_ioc.c_cc > 0) { - cc = q_to_b(&pti->pt_ioc, buf, - MIN(pti->pt_ioc.c_cc, BUFSIZ)); - if (cc <= 0) /* impossible? */ - break; - error = uiomove(buf, cc, UIO_READ, uio); - } - return (error); - } if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) break; } @@ -323,7 +323,7 @@ ptcread(dev, uio, flag) ttyin, 0)) return (error); } - if (pti->pt_flags & (PF_PKT|PF_UCNTL|PF_TIOC)) + 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)); @@ -331,23 +331,18 @@ ptcread(dev, uio, flag) break; error = uiomove(buf, cc, uio); } - if (tp->t_outq.c_cc <= TTLOWAT(tp) && !(pti->pt_flags & PF_BLOCK)) - ptswake(tp); - return (error); -} - -ptswake(tp) - register struct tty *tp; -{ - if (tp->t_state&TS_ASLEEP) { - tp->t_state &= ~TS_ASLEEP; - wakeup((caddr_t)&tp->t_outq); - } - if (tp->t_wsel) { - selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); - tp->t_wsel = 0; - tp->t_state &= ~TS_WCOLL; + 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); + } + if (tp->t_wsel) { + selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); + tp->t_wsel = 0; + tp->t_state &= ~TS_WCOLL; + } } + return (error); } ptsstop(tp, flush) @@ -373,14 +368,14 @@ ptsstop(tp, flush) ptcwakeup(tp, flag); } -ptcselect(dev, rw) +ptcselect(dev, rw, p) dev_t dev; int rw; + struct proc *p; { - struct proc *curp = curproc; register struct tty *tp = &pt_tty[minor(dev)]; struct pt_ioctl *pti = &pt_ioctl[minor(dev)]; - struct proc *p; + struct proc *prev; int s; if ((tp->t_state&TS_CARR_ON) == 0) @@ -403,13 +398,12 @@ ptcselect(dev, rw) case 0: /* exceptional */ if ((tp->t_state&TS_ISOPEN) && (pti->pt_flags&PF_PKT && pti->pt_send || - pti->pt_flags&PF_TIOC && pti->pt_ioc.c_cc || pti->pt_flags&PF_UCNTL && pti->pt_ucntl)) return (1); - if ((p = pti->pt_selr) && p->p_wchan == (caddr_t)&selwait) + if ((prev = pti->pt_selr) && prev->p_wchan == (caddr_t)&selwait) pti->pt_flags |= PF_RCOLL; else - pti->pt_selr = curp; + pti->pt_selr = p; break; @@ -425,10 +419,10 @@ ptcselect(dev, rw) return (1); } } - if ((p = pti->pt_selw) && p->p_wchan == (caddr_t)&selwait) + if ((prev = pti->pt_selw) && prev->p_wchan == (caddr_t)&selwait) pti->pt_flags |= PF_WCOLL; else - pti->pt_selw = curp; + pti->pt_selw = p; break; } @@ -558,14 +552,7 @@ ptyioctl(dev, cmd, data, flag) } return(0); } else - if (cdevsw[major(dev)].d_open == ptcopen) { - if ((cmd & 0xffff) == (TIOCIOANS(0) & 0xffff)) { - if (!(pti->pt_flags & PF_LIOC) || pti->pt_ioc.c_cc) - return (EINVAL); - (void) b_to_q(data, IOCPARM_LEN(cmd), &pti->pt_ioc); - wakeup((caddr_t)&pti->pt_ioc); - return (0); - } + if (cdevsw[major(dev)].d_open == ptcopen) switch (cmd) { case TIOCGPGRP: @@ -594,30 +581,6 @@ ptyioctl(dev, cmd, data, flag) pti->pt_flags &= ~PF_UCNTL; return (0); - case TIOCTIOC: - if (*(int *)data) { - if (pti->pt_flags & PF_UCNTL) - return (EINVAL); - pti->pt_flags |= PF_TIOC; - } else { - pti->pt_flags &= ~(PF_TIOC|PF_LIOC|PF_WIOC); - while (pti->pt_ioc.c_cc) - (void) getc(&pti->pt_ioc); - wakeup((caddr_t)&pti->pt_ioc); - } - return (0); - - case TIOCBLK: - if (*(int *)data) - pti->pt_flags |= PF_BLOCK; - else { - if (pti->pt_flags & PF_OWAIT) - wakeup((caddr_t)pti + 1); - pti->pt_flags &= ~(PF_BLOCK|PF_OWAIT); - ptswake(tp); - } - return (0); - case TIOCREMOTE: if (*(int *)data) pti->pt_flags |= PF_REMOTE; @@ -626,10 +589,6 @@ ptyioctl(dev, cmd, data, flag) ttyflush(tp, FREAD|FWRITE); return (0); - case FIONREAD: - *(int *)data = tp->t_outq.c_cc; - return (0); - case TIOCSETP: case TIOCSETN: case TIOCSETD: @@ -651,69 +610,6 @@ ptyioctl(dev, cmd, data, flag) ttyinfo(tp); return(0); } - } else if (pti->pt_flags & PF_TIOC) { - while (pti->pt_flags & PF_LIOC) { - pti->pt_flags |= PF_WIOC; - switch (tsleep((caddr_t)&pti->pt_flags,TTIPRI-1,5*hz)) { - case TS_OK: - continue; - case TS_SIG: - case TS_TIME: - return (EBUSY); - } - } - pti->pt_flags |= PF_LIOC | PF_BLOCK; - while (pti->pt_ioc.c_cc) - (void) getc(&pti->pt_ioc); - (void) b_to_q(&cmd, sizeof cmd, &pti->pt_ioc); - if (cmd & IOC_IN) - (void) b_to_q(data, IOCPARM_LEN(cmd), &pti->pt_ioc); - ptcwakeup(tp, FREAD); - switch (tsleep((caddr_t)&pti->pt_ioc, TTIPRI-1, 5*hz)) { - case TS_SIG: - case TS_TIME: - while (pti->pt_ioc.c_cc) - (void) getc(&pti->pt_ioc); - if (pti->pt_flags & PF_WIOC) - wakeup((caddr_t)&pti->pt_flags); - if (pti->pt_flags & PF_OWAIT) - wakeup((caddr_t)pti + 1); - pti->pt_flags &= ~(PF_LIOC|PF_WIOC|PF_BLOCK|PF_OWAIT); - ptswake(tp); - return (EBUSY); - case TS_OK: - break; - } - if (pti->pt_ioc.c_cc == 0) { - if (pti->pt_flags & PF_WIOC) - wakeup((caddr_t)&pti->pt_flags); - if (pti->pt_flags & PF_OWAIT) - wakeup((caddr_t)pti + 1); - pti->pt_flags &= ~(PF_LIOC|PF_WIOC|PF_BLOCK|PF_OWAIT); - ptswake(tp); - goto doioctl; - } - if (q_to_b(&pti->pt_ioc, &error, sizeof error) != sizeof error) - error = EINVAL; - if (error == 0 && cmd & IOC_OUT) { - if (IOCPARM_LEN(cmd) != pti->pt_ioc.c_cc) - error = EINVAL; - else - (void) q_to_b(&pti->pt_ioc, data, - pti->pt_ioc.c_cc); - } - while (pti->pt_ioc.c_cc) - (void) getc(&pti->pt_ioc); - if (pti->pt_flags & PF_WIOC) - wakeup((caddr_t)&pti->pt_flags); - if (pti->pt_flags & PF_OWAIT) - wakeup((caddr_t)pti + 1); - pti->pt_flags &= ~(PF_LIOC|PF_WIOC|PF_BLOCK|PF_OWAIT); - ptswake(tp); - return (error); - } - - doioctl: error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); if (error < 0) error = ttioctl(tp, cmd, data, flag); @@ -722,22 +618,13 @@ ptyioctl(dev, cmd, data, flag) * pty's can't be switched to disciplines which overwrite * the queues. We can't tell anything about the discipline * from here... - * - * Nb: this is not really good enough, the line disc open routine - * may have done anything at all, no guarantees that close - * will fix it. This also has the effect of losing the - * previous discipline, which an error on a TIOCSETD shouldn't - * do... Sometime it should be done via an explicit check - * for TIOCSETD, then check to see what linesw[new_number].l_rint - * really is. */ if (linesw[tp->t_line].l_rint != ttyinput) { - (*linesw[tp->t_line].l_close)(tp); + (*linesw[tp->t_line].l_close)(tp, flag); tp->t_line = TTYDISC; (void)(*linesw[tp->t_line].l_open)(dev, tp, flag); error = ENOTTY; } - if (error < 0) { if (pti->pt_flags & PF_UCNTL && (cmd & ~0xff) == UIOCCMD(0)) {