From 8416877c8da5a637321121d8cad70419dd27fe59 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 9 Dec 2013 18:06:07 -0500 Subject: n_tty: Fix apparent order of echoed output commit 1075a6e2dc7e2a96efc417b98dd98f57fdae985d upstream. With block processing of echoed output, observed output order is still required. Push completed echoes and echo commands prior to output. Introduce echo_mark echo buffer index, which tracks completed echo commands; ie., those submitted via commit_echoes but which may not have been committed. Ensure that completed echoes are output prior to subsequent terminal writes in process_echoes(). Fixes newline/prompt output order in cooked mode shell. Reported-by: Karl Dahlke Reported-by: Mikulas Patocka Signed-off-by: Peter Hurley Tested-by: Karl Dahlke Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 4d6f430..d4a89db 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -93,6 +93,7 @@ struct n_tty_data { size_t canon_head; size_t echo_head; size_t echo_commit; + size_t echo_mark; DECLARE_BITMAP(char_map, 256); /* private to n_tty_receive_overrun (single-threaded) */ @@ -336,6 +337,7 @@ static void reset_buffer_flags(struct n_tty_data *ldata) { ldata->read_head = ldata->canon_head = ldata->read_tail = 0; ldata->echo_head = ldata->echo_tail = ldata->echo_commit = 0; + ldata->echo_mark = 0; ldata->line_start = 0; ldata->erasing = 0; @@ -787,6 +789,7 @@ static void commit_echoes(struct tty_struct *tty) size_t head; head = ldata->echo_head; + ldata->echo_mark = head; old = ldata->echo_commit - ldata->echo_tail; /* Process committed echoes if the accumulated # of bytes @@ -811,10 +814,11 @@ static void process_echoes(struct tty_struct *tty) size_t echoed; if ((!L_ECHO(tty) && !L_ECHONL(tty)) || - ldata->echo_commit == ldata->echo_tail) + ldata->echo_mark == ldata->echo_tail) return; mutex_lock(&ldata->output_lock); + ldata->echo_commit = ldata->echo_mark; echoed = __process_echoes(tty); mutex_unlock(&ldata->output_lock); @@ -822,6 +826,7 @@ static void process_echoes(struct tty_struct *tty) tty->ops->flush_chars(tty); } +/* NB: echo_mark and echo_head should be equivalent here */ static void flush_echoes(struct tty_struct *tty) { struct n_tty_data *ldata = tty->disc_data; -- cgit v0.10.2