diff options
Diffstat (limited to 'drivers/tty/n_tty.c')
| -rw-r--r-- | drivers/tty/n_tty.c | 49 | 
1 files changed, 27 insertions, 22 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index c9a9ddd1d0bc..7a744b69c3d1 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1758,8 +1758,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)  		canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON;  	if (canon_change) {  		bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); -		ldata->line_start = 0; -		ldata->canon_head = ldata->read_tail; +		ldata->line_start = ldata->canon_head = ldata->read_tail;  		ldata->erasing = 0;  		ldata->lnext = 0;  	} @@ -2184,28 +2183,34 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,  		if (!input_available_p(tty, 0)) {  			if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { -				retval = -EIO; -				break; -			} -			if (tty_hung_up_p(file)) -				break; -			if (!timeout) -				break; -			if (file->f_flags & O_NONBLOCK) { -				retval = -EAGAIN; -				break; -			} -			if (signal_pending(current)) { -				retval = -ERESTARTSYS; -				break; -			} -			n_tty_set_room(tty); -			up_read(&tty->termios_rwsem); +				up_read(&tty->termios_rwsem); +				tty_flush_to_ldisc(tty); +				down_read(&tty->termios_rwsem); +				if (!input_available_p(tty, 0)) { +					retval = -EIO; +					break; +				} +			} else { +				if (tty_hung_up_p(file)) +					break; +				if (!timeout) +					break; +				if (file->f_flags & O_NONBLOCK) { +					retval = -EAGAIN; +					break; +				} +				if (signal_pending(current)) { +					retval = -ERESTARTSYS; +					break; +				} +				n_tty_set_room(tty); +				up_read(&tty->termios_rwsem); -			timeout = schedule_timeout(timeout); +				timeout = schedule_timeout(timeout); -			down_read(&tty->termios_rwsem); -			continue; +				down_read(&tty->termios_rwsem); +				continue; +			}  		}  		__set_current_state(TASK_RUNNING);  | 
