diff options
Diffstat (limited to 'drivers/char/n_tty.c')
-rw-r--r-- | drivers/char/n_tty.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index bdae8327143c..428f4fe0b5f7 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -1102,6 +1102,11 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
1102 | if (I_IUCLC(tty) && L_IEXTEN(tty)) | 1102 | if (I_IUCLC(tty) && L_IEXTEN(tty)) |
1103 | c = tolower(c); | 1103 | c = tolower(c); |
1104 | 1104 | ||
1105 | if (L_EXTPROC(tty)) { | ||
1106 | put_tty_queue(c, tty); | ||
1107 | return; | ||
1108 | } | ||
1109 | |||
1105 | if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && | 1110 | if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && |
1106 | I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty) && | 1111 | I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty) && |
1107 | c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) && c != SUSP_CHAR(tty)) { | 1112 | c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) && c != SUSP_CHAR(tty)) { |
@@ -1409,7 +1414,8 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1409 | 1414 | ||
1410 | n_tty_set_room(tty); | 1415 | n_tty_set_room(tty); |
1411 | 1416 | ||
1412 | if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { | 1417 | if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || |
1418 | L_EXTPROC(tty)) { | ||
1413 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 1419 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
1414 | if (waitqueue_active(&tty->read_wait)) | 1420 | if (waitqueue_active(&tty->read_wait)) |
1415 | wake_up_interruptible(&tty->read_wait); | 1421 | wake_up_interruptible(&tty->read_wait); |
@@ -1585,7 +1591,7 @@ static int n_tty_open(struct tty_struct *tty) | |||
1585 | static inline int input_available_p(struct tty_struct *tty, int amt) | 1591 | static inline int input_available_p(struct tty_struct *tty, int amt) |
1586 | { | 1592 | { |
1587 | tty_flush_to_ldisc(tty); | 1593 | tty_flush_to_ldisc(tty); |
1588 | if (tty->icanon) { | 1594 | if (tty->icanon && !L_EXTPROC(tty)) { |
1589 | if (tty->canon_data) | 1595 | if (tty->canon_data) |
1590 | return 1; | 1596 | return 1; |
1591 | } else if (tty->read_cnt >= (amt ? amt : 1)) | 1597 | } else if (tty->read_cnt >= (amt ? amt : 1)) |
@@ -1632,6 +1638,11 @@ static int copy_from_read_buf(struct tty_struct *tty, | |||
1632 | spin_lock_irqsave(&tty->read_lock, flags); | 1638 | spin_lock_irqsave(&tty->read_lock, flags); |
1633 | tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1); | 1639 | tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1); |
1634 | tty->read_cnt -= n; | 1640 | tty->read_cnt -= n; |
1641 | /* Turn single EOF into zero-length read */ | ||
1642 | if (L_EXTPROC(tty) && tty->icanon && n == 1) { | ||
1643 | if (!tty->read_cnt && (*b)[n-1] == EOF_CHAR(tty)) | ||
1644 | n--; | ||
1645 | } | ||
1635 | spin_unlock_irqrestore(&tty->read_lock, flags); | 1646 | spin_unlock_irqrestore(&tty->read_lock, flags); |
1636 | *b += n; | 1647 | *b += n; |
1637 | *nr -= n; | 1648 | *nr -= n; |
@@ -1812,7 +1823,7 @@ do_it_again: | |||
1812 | nr--; | 1823 | nr--; |
1813 | } | 1824 | } |
1814 | 1825 | ||
1815 | if (tty->icanon) { | 1826 | if (tty->icanon && !L_EXTPROC(tty)) { |
1816 | /* N.B. avoid overrun if nr == 0 */ | 1827 | /* N.B. avoid overrun if nr == 0 */ |
1817 | while (nr && tty->read_cnt) { | 1828 | while (nr && tty->read_cnt) { |
1818 | int eol; | 1829 | int eol; |