Browse Source

n_tty: Fix stale echo output

When echoes cannot be flushed to output (usually because the tty
has no more write room) and L_ECHO is subsequently turned off, then
when L_ECHO is turned back on, stale echoes are output.

Output completed echoes regardless of the L_ECHO setting:
  1. before normal writes to that tty
  2. if the tty was stopped by soft flow control and is being
     restarted

Reported-by: Mikulas Patocka <mpatocka@redhat.com>
Cc: <stable@vger.kernel.org> # 3.13.x
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Peter Hurley 11 years ago
parent
commit
e2613be509
1 changed files with 7 additions and 5 deletions
  1. 7 5
      drivers/tty/n_tty.c

+ 7 - 5
drivers/tty/n_tty.c

@@ -817,8 +817,7 @@ static void process_echoes(struct tty_struct *tty)
 	struct n_tty_data *ldata = tty->disc_data;
 	struct n_tty_data *ldata = tty->disc_data;
 	size_t echoed;
 	size_t echoed;
 
 
-	if ((!L_ECHO(tty) && !L_ECHONL(tty)) ||
-	    ldata->echo_mark == ldata->echo_tail)
+	if (ldata->echo_mark == ldata->echo_tail)
 		return;
 		return;
 
 
 	mutex_lock(&ldata->output_lock);
 	mutex_lock(&ldata->output_lock);
@@ -1244,7 +1243,8 @@ n_tty_receive_signal_char(struct tty_struct *tty, int signal, unsigned char c)
 	if (L_ECHO(tty)) {
 	if (L_ECHO(tty)) {
 		echo_char(c, tty);
 		echo_char(c, tty);
 		commit_echoes(tty);
 		commit_echoes(tty);
-	}
+	} else
+		process_echoes(tty);
 	isig(signal, tty);
 	isig(signal, tty);
 	return;
 	return;
 }
 }
@@ -1274,7 +1274,7 @@ n_tty_receive_char_special(struct tty_struct *tty, unsigned char c)
 	if (I_IXON(tty)) {
 	if (I_IXON(tty)) {
 		if (c == START_CHAR(tty)) {
 		if (c == START_CHAR(tty)) {
 			start_tty(tty);
 			start_tty(tty);
-			commit_echoes(tty);
+			process_echoes(tty);
 			return 0;
 			return 0;
 		}
 		}
 		if (c == STOP_CHAR(tty)) {
 		if (c == STOP_CHAR(tty)) {
@@ -1820,8 +1820,10 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
 	 * Fix tty hang when I_IXON(tty) is cleared, but the tty
 	 * Fix tty hang when I_IXON(tty) is cleared, but the tty
 	 * been stopped by STOP_CHAR(tty) before it.
 	 * been stopped by STOP_CHAR(tty) before it.
 	 */
 	 */
-	if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped)
+	if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped) {
 		start_tty(tty);
 		start_tty(tty);
+		process_echoes(tty);
+	}
 
 
 	/* The termios change make the tty ready for I/O */
 	/* The termios change make the tty ready for I/O */
 	if (waitqueue_active(&tty->write_wait))
 	if (waitqueue_active(&tty->write_wait))