mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-15 10:17:20 +00:00
Merge a bunch of changes that where done in tty_pty.c after tty_pts.c was
forked from it, but missed from some reason.
This commit is contained in:
parent
b258da0fa9
commit
23c15e6437
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=154911
@ -153,11 +153,8 @@ static LIST_HEAD(,pt_desc) pt_free_list;
|
||||
|
||||
#define PF_PKT 0x008 /* packet mode */
|
||||
#define PF_STOPPED 0x010 /* user told stopped */
|
||||
#define PF_REMOTE 0x020 /* remote and flow controlled input */
|
||||
#define PF_NOSTOP 0x040
|
||||
#define PF_UCNTL 0x080 /* user control mode */
|
||||
#define PF_COPEN 0x100 /* control half open */
|
||||
#define PF_SOPEN 0x200 /* slave half open */
|
||||
|
||||
static unsigned int next_avail_nb;
|
||||
|
||||
@ -265,14 +262,9 @@ ptsopen(struct cdev *dev, int flag, int devtype, struct thread *td)
|
||||
|
||||
pt = dev->si_drv1;
|
||||
tp = dev->si_tty;
|
||||
if ((tp->t_state & TS_ISOPEN) == 0) {
|
||||
ttychars(tp); /* Set up default chars */
|
||||
tp->t_iflag = TTYDEF_IFLAG;
|
||||
tp->t_oflag = TTYDEF_OFLAG;
|
||||
tp->t_lflag = TTYDEF_LFLAG;
|
||||
tp->t_cflag = TTYDEF_CFLAG;
|
||||
tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
|
||||
} else if (tp->t_state & TS_XCLUDE && suser(td)) {
|
||||
if ((tp->t_state & TS_ISOPEN) == 0)
|
||||
ttyinitmode(tp, 1, 0);
|
||||
else if (tp->t_state & TS_XCLUDE && suser(td)) {
|
||||
return (EBUSY);
|
||||
} else if (pt->pt_prison != td->td_ucred->cr_prison) {
|
||||
return (EBUSY);
|
||||
@ -314,57 +306,11 @@ ptsclose(struct cdev *dev, int flag, int mode, struct thread *td)
|
||||
static int
|
||||
ptsread(struct cdev *dev, struct uio *uio, int flag)
|
||||
{
|
||||
struct thread *td = curthread;
|
||||
struct proc *p = td->td_proc;
|
||||
struct tty *tp = dev->si_tty;
|
||||
struct pt_desc *pt = dev->si_drv1;
|
||||
struct pgrp *pg;
|
||||
int error = 0;
|
||||
|
||||
again:
|
||||
if (pt->pt_flags & PF_REMOTE) {
|
||||
while (isbackground(p, tp)) {
|
||||
sx_slock(&proctree_lock);
|
||||
PROC_LOCK(p);
|
||||
if (SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTIN) ||
|
||||
SIGISMEMBER(td->td_sigmask, SIGTTIN) ||
|
||||
p->p_pgrp->pg_jobc == 0 || p->p_flag & P_PPWAIT) {
|
||||
PROC_UNLOCK(p);
|
||||
sx_sunlock(&proctree_lock);
|
||||
return (EIO);
|
||||
}
|
||||
pg = p->p_pgrp;
|
||||
PROC_UNLOCK(p);
|
||||
PGRP_LOCK(pg);
|
||||
sx_sunlock(&proctree_lock);
|
||||
pgsignal(pg, SIGTTIN, 1);
|
||||
PGRP_UNLOCK(pg);
|
||||
error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ptsbg",
|
||||
0);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
if (tp->t_canq.c_cc == 0) {
|
||||
if (flag & IO_NDELAY)
|
||||
return (EWOULDBLOCK);
|
||||
error = ttysleep(tp, TSA_PTS_READ(tp), TTIPRI | PCATCH,
|
||||
"ptsin", 0);
|
||||
if (error)
|
||||
return (error);
|
||||
goto again;
|
||||
}
|
||||
while (tp->t_canq.c_cc > 1 && uio->uio_resid > 0)
|
||||
if (ureadc(getc(&tp->t_canq), uio) < 0) {
|
||||
error = EFAULT;
|
||||
break;
|
||||
}
|
||||
if (tp->t_canq.c_cc == 1)
|
||||
(void) getc(&tp->t_canq);
|
||||
if (tp->t_canq.c_cc)
|
||||
return (error);
|
||||
} else
|
||||
if (tp->t_oproc)
|
||||
ttyld_read(tp, uio, flag);
|
||||
if (tp->t_oproc)
|
||||
error = ttyld_read(tp, uio, flag);
|
||||
ptcwakeup(tp, FWRITE);
|
||||
return (error);
|
||||
}
|
||||
@ -539,7 +485,7 @@ ptcread(struct cdev *dev, struct uio *uio, int flag)
|
||||
}
|
||||
if ((tp->t_state & TS_CONNECTED) == 0)
|
||||
return (0); /* EOF */
|
||||
if (flag & IO_NDELAY)
|
||||
if (flag & O_NONBLOCK)
|
||||
return (EWOULDBLOCK);
|
||||
error = tsleep(TSA_PTC_READ(tp), TTIPRI | PCATCH, "ptcin", 0);
|
||||
if (error)
|
||||
@ -605,9 +551,7 @@ ptcpoll(struct cdev *dev, int events, struct thread *td)
|
||||
|
||||
if (events & (POLLOUT | POLLWRNORM))
|
||||
if (tp->t_state & TS_ISOPEN &&
|
||||
((pt->pt_flags & PF_REMOTE) ?
|
||||
(tp->t_canq.c_cc == 0) :
|
||||
((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG - 2) ||
|
||||
(((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG - 2) ||
|
||||
(tp->t_canq.c_cc == 0 && (tp->t_lflag & ICANON)))))
|
||||
revents |= events & (POLLOUT | POLLWRNORM);
|
||||
|
||||
@ -635,52 +579,11 @@ ptcwrite(struct cdev *dev, struct uio *uio, int flag)
|
||||
int cc = 0;
|
||||
u_char locbuf[BUFSIZ];
|
||||
int cnt = 0;
|
||||
struct pt_desc *pt = dev->si_drv1;
|
||||
int error = 0;
|
||||
|
||||
again:
|
||||
if ((tp->t_state&TS_ISOPEN) == 0)
|
||||
goto block;
|
||||
if (pt->pt_flags & PF_REMOTE) {
|
||||
if (tp->t_canq.c_cc)
|
||||
goto block;
|
||||
while ((uio->uio_resid > 0 || cc > 0) &&
|
||||
tp->t_canq.c_cc < TTYHOG - 1) {
|
||||
if (cc == 0) {
|
||||
cc = min(uio->uio_resid, BUFSIZ);
|
||||
cc = min(cc, TTYHOG - 1 - tp->t_canq.c_cc);
|
||||
cp = locbuf;
|
||||
error = uiomove(cp, cc, uio);
|
||||
if (error)
|
||||
return (error);
|
||||
/* check again for safety */
|
||||
if ((tp->t_state & TS_ISOPEN) == 0) {
|
||||
/* adjust as usual */
|
||||
uio->uio_resid += cc;
|
||||
return (EIO);
|
||||
}
|
||||
}
|
||||
if (cc > 0) {
|
||||
cc = b_to_q((char *)cp, cc, &tp->t_canq);
|
||||
/*
|
||||
* XXX we don't guarantee that the canq size
|
||||
* is >= TTYHOG, so the above b_to_q() may
|
||||
* leave some bytes uncopied. However, space
|
||||
* is guaranteed for the null terminator if
|
||||
* we don't fail here since (TTYHOG - 1) is
|
||||
* not a multiple of CBSIZE.
|
||||
*/
|
||||
if (cc > 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* adjust for data copied in but not written */
|
||||
uio->uio_resid += cc;
|
||||
(void) putc(0, &tp->t_canq);
|
||||
ttwakeup(tp);
|
||||
wakeup(TSA_PTS_READ(tp));
|
||||
return (0);
|
||||
}
|
||||
while (uio->uio_resid > 0 || cc > 0) {
|
||||
if (cc == 0) {
|
||||
cc = min(uio->uio_resid, BUFSIZ);
|
||||
|
Loading…
Reference in New Issue
Block a user