Print this page
14249 pseudo-terminal nomenclature should reflect POSIX
Change-Id: Ib4a3cef899ff4c71b09cb0dc6878863c5e8357bc

*** 9,20 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* ! * PTY - Stream "pseudo-tty" device. For each "controller" side ! * it connects to a "slave" side. */ #include <sys/param.h> #include <sys/systm.h> --- 9,20 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* ! * PTY - Stream "pseudo-terminal" device. For each "manager" side it connects ! * to a "subsidiary" side. */ #include <sys/param.h> #include <sys/systm.h>
*** 27,37 **** #include <sys/stream.h> #include <sys/tty.h> #include <sys/user.h> #include <sys/conf.h> #include <sys/file.h> ! #include <sys/vnode.h> /* 1/0 on the vomit meter */ #include <sys/proc.h> #include <sys/uio.h> #include <sys/errno.h> #include <sys/strsubr.h> #include <sys/poll.h> --- 27,37 ---- #include <sys/stream.h> #include <sys/tty.h> #include <sys/user.h> #include <sys/conf.h> #include <sys/file.h> ! #include <sys/vnode.h> #include <sys/proc.h> #include <sys/uio.h> #include <sys/errno.h> #include <sys/strsubr.h> #include <sys/poll.h>
*** 114,126 **** /* * Module linkage information for the kernel. */ static struct modldrv modldrv = { ! &mod_driverops, /* Type of module. This one is a pseudo driver */ "tty pseudo driver control 'ptc'", ! &ptc_ops, /* driver ops */ }; static struct modlinkage modlinkage = { MODREV_1, &modldrv, --- 114,126 ---- /* * Module linkage information for the kernel. */ static struct modldrv modldrv = { ! &mod_driverops, "tty pseudo driver control 'ptc'", ! &ptc_ops, }; static struct modlinkage modlinkage = { MODREV_1, &modldrv,
*** 234,249 **** mutex_destroy(&pty_softc[dev].ptc_lock); } } /* ! * Controller side. This is not, alas, a streams device; there are too * many old features that we must support and that don't work well * with streams. */ - /*ARGSUSED*/ int ptcopen(dev_t *devp, int flag, int otyp, struct cred *cred) { dev_t dev = *devp; struct pty *pty; --- 234,248 ---- mutex_destroy(&pty_softc[dev].ptc_lock); } } /* ! * Manager side. This is not, alas, a streams device; there are too * many old features that we must support and that don't work well * with streams. */ int ptcopen(dev_t *devp, int flag, int otyp, struct cred *cred) { dev_t dev = *devp; struct pty *pty;
*** 254,274 **** } pty = &pty_softc[getminor(dev)]; mutex_enter(&pty->ptc_lock); if (pty->pt_flags & PF_CARR_ON) { mutex_exit(&pty->ptc_lock); ! return (EIO); /* controller is exclusive use */ /* XXX - should be EBUSY! */ } if (pty->pt_flags & PF_WOPEN) { pty->pt_flags &= ~PF_WOPEN; cv_broadcast(&pty->pt_cv_flags); } if ((q = pty->pt_ttycommon.t_readq) != NULL) { /* ! * Send an un-hangup to the slave, since "carrier" is * coming back up. Make sure we're doing canonicalization. */ (void) putctl(q, M_UNHANGUP); (void) putctl1(q, M_CTL, MC_DOCANON); } --- 253,273 ---- } pty = &pty_softc[getminor(dev)]; mutex_enter(&pty->ptc_lock); if (pty->pt_flags & PF_CARR_ON) { mutex_exit(&pty->ptc_lock); ! return (EIO); /* manager is exclusive use */ /* XXX - should be EBUSY! */ } if (pty->pt_flags & PF_WOPEN) { pty->pt_flags &= ~PF_WOPEN; cv_broadcast(&pty->pt_cv_flags); } if ((q = pty->pt_ttycommon.t_readq) != NULL) { /* ! * Send an un-hangup to the subsidiary, since "carrier" is * coming back up. Make sure we're doing canonicalization. */ (void) putctl(q, M_UNHANGUP); (void) putctl1(q, M_CTL, MC_DOCANON); }
*** 278,288 **** mutex_exit(&pty->ptc_lock); return (0); } - /*ARGSUSED1*/ int ptcclose(dev_t dev, int flag, int otyp, struct cred *cred) { struct pty *pty; mblk_t *bp; --- 277,286 ----
*** 291,309 **** pty = &pty_softc[getminor(dev)]; mutex_enter(&pty->ptc_lock); if ((q = pty->pt_ttycommon.t_readq) != NULL) { /* ! * Send a hangup to the slave, since "carrier" is dropping. */ (void) putctl(q, M_HANGUP); } /* ! * Clear out all the controller-side state. This also * clears PF_CARR_ON, which is correct because the ! * "carrier" is dropping since the controller process * is going away. */ pty->pt_flags &= (PF_WOPEN|PF_STOPPED|PF_NOSTOP); while ((bp = pty->pt_stuffqfirst) != NULL) { if ((pty->pt_stuffqfirst = bp->b_next) == NULL) --- 289,307 ---- pty = &pty_softc[getminor(dev)]; mutex_enter(&pty->ptc_lock); if ((q = pty->pt_ttycommon.t_readq) != NULL) { /* ! * Send a hangup to the subsidiary, since "carrier" is dropping. */ (void) putctl(q, M_HANGUP); } /* ! * Clear out all the manager-side state. This also * clears PF_CARR_ON, which is correct because the ! * "carrier" is dropping since the manager process * is going away. */ pty->pt_flags &= (PF_WOPEN|PF_STOPPED|PF_NOSTOP); while ((bp = pty->pt_stuffqfirst) != NULL) { if ((pty->pt_stuffqfirst = bp->b_next) == NULL)
*** 327,340 **** unsigned char tmp; ssize_t cc; int error; off_t off; - #ifdef lint - cred = cred; - #endif - off = uio->uio_offset; mutex_enter(&pty->ptc_lock); for (;;) { --- 325,334 ----
*** 473,490 **** goto out; } /* * There's no data available. ! * We want to block until the slave is open, and there's ! * something to read; but if we lost the slave or we're NBIO, ! * then return the appropriate error instead. POSIX-style ! * non-block has top billing and gives -1 with errno = EAGAIN, ! * BSD-style comes next and gives -1 with errno = EWOULDBLOCK, ! * SVID-style comes last and gives 0. */ ! if (pty->pt_flags & PF_SLAVEGONE) { error = EIO; goto out; } if (uio->uio_fmode & FNONBLOCK) { error = EAGAIN; --- 467,484 ---- goto out; } /* * There's no data available. ! * We want to block until the subsidiary is open, and there's ! * something to read; but if we lost the subsidiary or we're ! * NBIO, then return the appropriate error instead. ! * POSIX-style non-block has top billing and gives -1 with ! * errno = EAGAIN, BSD-style comes next and gives -1 with ! * errno = EWOULDBLOCK, SVID-style comes last and gives 0. */ ! if (pty->pt_flags & PF_SUBSIDGONE) { error = EIO; goto out; } if (uio->uio_fmode & FNONBLOCK) { error = EAGAIN;
*** 530,544 **** int error = 0; off_t off; off = uio->uio_offset; - #ifdef lint - cred = cred; - #endif - - mutex_enter(&pty->ptc_lock); again: while (pty->pt_flags & PF_WRITE) { pty->pt_flags |= PF_WWRITE; --- 524,533 ----
*** 548,560 **** pty->pt_flags |= PF_WRITE; if ((q = pty->pt_ttycommon.t_readq) == NULL) { /* ! * Wait for slave to open. */ ! if (pty->pt_flags & PF_SLAVEGONE) { error = EIO; goto out; } if (uio->uio_fmode & FNONBLOCK) { error = EAGAIN; --- 537,549 ---- pty->pt_flags |= PF_WRITE; if ((q = pty->pt_ttycommon.t_readq) == NULL) { /* ! * Wait for subsidiary to open. */ ! if (pty->pt_flags & PF_SUBSIDGONE) { error = EIO; goto out; } if (uio->uio_fmode & FNONBLOCK) { error = EAGAIN;
*** 586,598 **** written = 0; if ((pty->pt_flags & PF_REMOTE) || uio->uio_resid > 0) { do { while (!canput(q)) { /* ! * Wait for slave's read queue to unclog. */ ! if (pty->pt_flags & PF_SLAVEGONE) { error = EIO; goto out; } if (uio->uio_fmode & FNONBLOCK) { if (!written) --- 575,587 ---- written = 0; if ((pty->pt_flags & PF_REMOTE) || uio->uio_resid > 0) { do { while (!canput(q)) { /* ! * Wait for subsidiary's read queue to unclog. */ ! if (pty->pt_flags & PF_SUBSIDGONE) { error = EIO; goto out; } if (uio->uio_fmode & FNONBLOCK) { if (!written)
*** 761,771 **** mutex_exit(&pty->ptc_lock); break; case TIOCSIGNAL: /* ! * Blast a M_PCSIG message up the slave stream; the * signal number is the argument to the "ioctl". */ copy_in(data, d_arg); mutex_enter(&pty->ptc_lock); if ((q = pty->pt_ttycommon.t_readq) != NULL) --- 750,760 ---- mutex_exit(&pty->ptc_lock); break; case TIOCSIGNAL: /* ! * Blast a M_PCSIG message up the subsidiary stream; the * signal number is the argument to the "ioctl". */ copy_in(data, d_arg); mutex_enter(&pty->ptc_lock); if ((q = pty->pt_ttycommon.t_readq) != NULL)
*** 792,802 **** pty->pt_flags &= ~PF_ASYNC; mutex_exit(&pty->ptc_lock); break; /* ! * These, at least, can work on the controller-side process * group. */ case FIOGETOWN: mutex_enter(&pty->ptc_lock); d_arg = -pty->pt_pgrp; --- 781,791 ---- pty->pt_flags &= ~PF_ASYNC; mutex_exit(&pty->ptc_lock); break; /* ! * These, at least, can work on the manager-side process * group. */ case FIOGETOWN: mutex_enter(&pty->ptc_lock); d_arg = -pty->pt_pgrp;
*** 811,823 **** mutex_exit(&pty->ptc_lock); break; case FIONREAD: { /* ! * Return the total number of bytes of data in all messages ! * in slave write queue, which is master read queue, unless a ! * special message would be read. */ mblk_t *mp; size_t count = 0; mutex_enter(&pty->ptc_lock); --- 800,812 ---- mutex_exit(&pty->ptc_lock); break; case FIONREAD: { /* ! * Return the total number of bytes of data in all messages in ! * subsidiary write queue, which is manager read queue, unless ! * a special message would be read. */ mblk_t *mp; size_t count = 0; mutex_enter(&pty->ptc_lock);
*** 914,930 **** return (EFAULT); break; /* * XXX These should not be here. The only reason why an ! * "ioctl" on the controller side should get the ! * slave side's process group is so that the process on ! * the controller side can send a signal to the slave * side's process group; however, this is better done * with TIOCSIGNAL, both because it doesn't require us ! * to know about the slave side's process group and because ! * the controller side process may not have permission to * send that signal to the entire process group. * * However, since vanilla 4BSD doesn't provide TIOCSIGNAL, * we can't just get rid of them. */ --- 903,919 ---- return (EFAULT); break; /* * XXX These should not be here. The only reason why an ! * "ioctl" on the manager side should get the ! * subsidiary side's process group is so that the process on ! * the manager side can send a signal to the subsidiary * side's process group; however, this is better done * with TIOCSIGNAL, both because it doesn't require us ! * to know about the subsidiary side's process group and because ! * the manager side process may not have permission to * send that signal to the entire process group. * * However, since vanilla 4BSD doesn't provide TIOCSIGNAL, * we can't just get rid of them. */
*** 931,943 **** case TIOCGPGRP: case TIOCSPGRP: /* * This is amazingly disgusting, but the stupid semantics of * 4BSD pseudo-ttys makes us do it. If we do one of these guys ! * on the controller side, it really applies to the slave-side * stream. It should NEVER have been possible to do ANY sort ! * of tty operations on the controller side, but it's too late * to fix that now. However, we won't waste our time implementing * anything that the original pseudo-tty driver didn't handle. */ case TIOCGETP: case TIOCSETP: --- 920,932 ---- case TIOCGPGRP: case TIOCSPGRP: /* * This is amazingly disgusting, but the stupid semantics of * 4BSD pseudo-ttys makes us do it. If we do one of these guys ! * on the manager side, it really applies to the subsidiary-side * stream. It should NEVER have been possible to do ANY sort ! * of tty operations on the manager side, but it's too late * to fix that now. However, we won't waste our time implementing * anything that the original pseudo-tty driver didn't handle. */ case TIOCGETP: case TIOCSETP:
*** 981,1002 **** struct pty *pty = &pty_softc[getminor(dev)]; pollhead_t *php = &ptcph; queue_t *q; int pos = 0; - #ifdef lint - anyyet = anyyet; - #endif if (polllock(php, &pty->ptc_lock) != 0) { *reventsp = POLLNVAL; return (0); } ASSERT(MUTEX_HELD(&pty->ptc_lock)); *reventsp = 0; ! if (pty->pt_flags & PF_SLAVEGONE) { if (events & (POLLIN|POLLRDNORM)) *reventsp |= (events & (POLLIN|POLLRDNORM)); if (events & (POLLOUT|POLLWRNORM)) *reventsp |= (events & (POLLOUT|POLLWRNORM)); mutex_exit(&pty->ptc_lock); --- 970,988 ---- struct pty *pty = &pty_softc[getminor(dev)]; pollhead_t *php = &ptcph; queue_t *q; int pos = 0; if (polllock(php, &pty->ptc_lock) != 0) { *reventsp = POLLNVAL; return (0); } ASSERT(MUTEX_HELD(&pty->ptc_lock)); *reventsp = 0; ! if (pty->pt_flags & PF_SUBSIDGONE) { if (events & (POLLIN|POLLRDNORM)) *reventsp |= (events & (POLLIN|POLLRDNORM)); if (events & (POLLOUT|POLLWRNORM)) *reventsp |= (events & (POLLOUT|POLLWRNORM)); mutex_exit(&pty->ptc_lock);