diff options
Diffstat (limited to 'drivers/tty/n_tty.c')
-rw-r--r-- | drivers/tty/n_tty.c | 54 |
1 files changed, 12 insertions, 42 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index a0285da02..e49c2bce5 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -201,7 +201,7 @@ static void n_tty_kick_worker(struct tty_struct *tty) */ WARN_RATELIMIT(test_bit(TTY_LDISC_HALTED, &tty->flags), "scheduling buffer work for halted ldisc\n"); - queue_work(system_unbound_wq, &tty->port->buf.work); + tty_buffer_restart_work(tty->port); } } @@ -1179,8 +1179,6 @@ static void n_tty_receive_break(struct tty_struct *tty) put_tty_queue('\0', ldata); } put_tty_queue('\0', ldata); - if (waitqueue_active(&tty->read_wait)) - wake_up_interruptible_poll(&tty->read_wait, POLLIN); } /** @@ -1237,8 +1235,6 @@ static void n_tty_receive_parity_error(struct tty_struct *tty, unsigned char c) put_tty_queue('\0', ldata); } else put_tty_queue(c, ldata); - if (waitqueue_active(&tty->read_wait)) - wake_up_interruptible_poll(&tty->read_wait, POLLIN); } static void @@ -2058,13 +2054,13 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, size_t eol; size_t tail; int ret, found = 0; - bool eof_push = 0; /* N.B. avoid overrun if nr == 0 */ - n = min(*nr, smp_load_acquire(&ldata->canon_head) - ldata->read_tail); - if (!n) + if (!*nr) return 0; + n = min(*nr + 1, smp_load_acquire(&ldata->canon_head) - ldata->read_tail); + tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1); size = min_t(size_t, tail + n, N_TTY_BUF_SIZE); @@ -2085,12 +2081,11 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, n = eol - tail; if (n > N_TTY_BUF_SIZE) n += N_TTY_BUF_SIZE; - n += found; - c = n; + c = n + found; - if (found && !ldata->push && read_buf(ldata, eol) == __DISABLED_CHAR) { - n--; - eof_push = !n && ldata->read_tail != ldata->line_start; + if (!found || read_buf(ldata, eol) != __DISABLED_CHAR) { + c = min(*nr, c); + n = c; } n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu size:%zu more:%zu\n", @@ -2120,7 +2115,7 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, ldata->push = 0; tty_audit_push(tty); } - return eof_push ? -EAGAIN : 0; + return 0; } extern ssize_t redirected_tty_write(struct file *, const char __user *, @@ -2142,37 +2137,15 @@ extern ssize_t redirected_tty_write(struct file *, const char __user *, static int job_control(struct tty_struct *tty, struct file *file) { - struct pid *pgrp; - /* Job control check -- must be done at start and after every sleep (POSIX.1 7.1.1.4). */ /* NOTE: not yet done after every sleep pending a thorough check of the logic of this change. -- jlc */ /* don't stop on /dev/console */ - if (file->f_op->write == redirected_tty_write || - current->signal->tty != tty) + if (file->f_op->write == redirected_tty_write) return 0; - rcu_read_lock(); - pgrp = task_pgrp(current); - - spin_lock_irq(&tty->ctrl_lock); - if (!tty->pgrp) - printk(KERN_ERR "n_tty_read: no tty->pgrp!\n"); - else if (pgrp != tty->pgrp) { - spin_unlock_irq(&tty->ctrl_lock); - if (is_ignored(SIGTTIN) || is_current_pgrp_orphaned()) { - rcu_read_unlock(); - return -EIO; - } - kill_pgrp(pgrp, SIGTTIN, 1); - rcu_read_unlock(); - set_thread_flag(TIF_SIGPENDING); - return -ERESTARTSYS; - } - spin_unlock_irq(&tty->ctrl_lock); - rcu_read_unlock(); - return 0; + return __tty_check_change(tty, SIGTTIN); } @@ -2299,10 +2272,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, if (ldata->icanon && !L_EXTPROC(tty)) { retval = canon_copy_from_read_buf(tty, &b, &nr); - if (retval == -EAGAIN) { - retval = 0; - continue; - } else if (retval) + if (retval) break; } else { int uncopied; |