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:
ed 2012-10-25 09:05:21 +00:00
parent 3d11eb1465
commit ae88b22791
3 changed files with 18 additions and 8 deletions

View File

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

View File

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

View File

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