Correct SIGTTIN handling.
In the old TTY layer, SIGTTIN was correctly handled like this: while (data should be read) { send SIGTTIN if not foreground process group read data } In the new TTY layer, however, this behaviour was changed, based on a false interpretation of the standard: send SIGTTIN if not foreground process group while (data should be read) { read data } Correct this by pushing tty_wait_background() into the ttydisc_read_*() functions. Reported by: koitsu PR: kern/173010 MFC after: 2 weeks
This commit is contained in:
parent
3d11eb1465
commit
ae88b22791
@ -361,7 +361,7 @@ tty_is_ctty(struct tty *tp, struct proc *p)
|
||||
return (p->p_session == tp->t_session && p->p_flag & P_CONTROLT);
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
tty_wait_background(struct tty *tp, struct thread *td, int sig)
|
||||
{
|
||||
struct proc *p = td->td_proc;
|
||||
@ -433,13 +433,6 @@ ttydev_read(struct cdev *dev, struct uio *uio, int ioflag)
|
||||
error = ttydev_enter(tp);
|
||||
if (error)
|
||||
goto done;
|
||||
|
||||
error = tty_wait_background(tp, curthread, SIGTTIN);
|
||||
if (error) {
|
||||
tty_unlock(tp);
|
||||
goto done;
|
||||
}
|
||||
|
||||
error = ttydisc_read(tp, uio, ioflag);
|
||||
tty_unlock(tp);
|
||||
|
||||
|
@ -126,6 +126,10 @@ ttydisc_read_canonical(struct tty *tp, struct uio *uio, int ioflag)
|
||||
breakc[n] = '\0';
|
||||
|
||||
do {
|
||||
error = tty_wait_background(tp, curthread, SIGTTIN);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
/*
|
||||
* Quite a tricky case: unlike the old TTY
|
||||
* implementation, this implementation copies data back
|
||||
@ -192,6 +196,10 @@ ttydisc_read_raw_no_timer(struct tty *tp, struct uio *uio, int ioflag)
|
||||
*/
|
||||
|
||||
for (;;) {
|
||||
error = tty_wait_background(tp, curthread, SIGTTIN);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
error = ttyinq_read_uio(&tp->t_inq, tp, uio,
|
||||
uio->uio_resid, 0);
|
||||
if (error)
|
||||
@ -229,6 +237,10 @@ ttydisc_read_raw_read_timer(struct tty *tp, struct uio *uio, int ioflag,
|
||||
timevaladd(&end, &now);
|
||||
|
||||
for (;;) {
|
||||
error = tty_wait_background(tp, curthread, SIGTTIN);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
error = ttyinq_read_uio(&tp->t_inq, tp, uio,
|
||||
uio->uio_resid, 0);
|
||||
if (error)
|
||||
@ -278,6 +290,10 @@ ttydisc_read_raw_interbyte_timer(struct tty *tp, struct uio *uio, int ioflag)
|
||||
*/
|
||||
|
||||
for (;;) {
|
||||
error = tty_wait_background(tp, curthread, SIGTTIN);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
error = ttyinq_read_uio(&tp->t_inq, tp, uio,
|
||||
uio->uio_resid, 0);
|
||||
if (error)
|
||||
|
@ -180,6 +180,7 @@ void tty_signal_sessleader(struct tty *tp, int signal);
|
||||
void tty_signal_pgrp(struct tty *tp, int signal);
|
||||
/* Waking up readers/writers. */
|
||||
int tty_wait(struct tty *tp, struct cv *cv);
|
||||
int tty_wait_background(struct tty *tp, struct thread *td, int sig);
|
||||
int tty_timedwait(struct tty *tp, struct cv *cv, int timo);
|
||||
void tty_wakeup(struct tty *tp, int flags);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user