Commit ff8cb0fd authored by Thomas Pfaff's avatar Thomas Pfaff Committed by Linus Torvalds

tty: N_TTY SIGIO only works for read

The N_TTY ldisc layer does not send SIGIO POLL_OUTs correctly when output is
possible due to flawed handling of the TTY_DO_WRITE_WAKEUP bit. It will
either send no SIGIOs at all or on every tty wakeup.

The fix is to set the bit when the tty driver write would block and test
and clear it on write wakeup.

[Merged with existing N_TTY patches and a small buglet fixed -- Alan]
Signed-off-by: default avatarThomas Pfaff <tpfaff@pcs.com>
Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent eff6937a
...@@ -1352,10 +1352,8 @@ static void n_tty_write_wakeup(struct tty_struct *tty) ...@@ -1352,10 +1352,8 @@ static void n_tty_write_wakeup(struct tty_struct *tty)
/* Write out any echoed characters that are still pending */ /* Write out any echoed characters that are still pending */
process_echoes(tty); process_echoes(tty);
if (tty->fasync) { if (tty->fasync && test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags))
set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
kill_fasync(&tty->fasync, SIGIO, POLL_OUT); kill_fasync(&tty->fasync, SIGIO, POLL_OUT);
}
} }
/** /**
...@@ -2014,6 +2012,8 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, ...@@ -2014,6 +2012,8 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
break_out: break_out:
__set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
remove_wait_queue(&tty->write_wait, &wait); remove_wait_queue(&tty->write_wait, &wait);
if (b - buf != nr && tty->fasync)
set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
return (b - buf) ? b - buf : retval; return (b - buf) ? b - buf : retval;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment