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);