diff options
author | Peter Hurley <peter@hurleysoftware.com> | 2013-06-15 07:28:28 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-06-17 15:55:11 -0400 |
commit | f6c8dbe6e50c6e5121d7b6644718207daa008221 (patch) | |
tree | f7200d98ecaa899fb2c83d6b58b88a20b302f936 /drivers/tty/tty_io.c | |
parent | a630fbfbb1beeffc5bbe542a7986bf2068874633 (diff) |
n_tty: Encapsulate minimum_to_wake within N_TTY
minimum_to_wake is unique to N_TTY processing, and belongs in
per-ldisc data.
Add the ldisc method, ldisc_ops::fasync(), to notify line disciplines
when signal-driven I/O is enabled or disabled. When enabled for N_TTY
(by fcntl(F_SETFL, O_ASYNC)), blocking reader/polls will be woken
for any readable input. When disabled, blocking reader/polls are not
woken until the read buffer is full.
Canonical mode (L_ICANON(tty), n_tty_data::icanon) is not affected by
the minimum_to_wake setting.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r-- | drivers/tty/tty_io.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 6464029e4860..bd88007fa6ea 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -2138,6 +2138,7 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait) | |||
2138 | static int __tty_fasync(int fd, struct file *filp, int on) | 2138 | static int __tty_fasync(int fd, struct file *filp, int on) |
2139 | { | 2139 | { |
2140 | struct tty_struct *tty = file_tty(filp); | 2140 | struct tty_struct *tty = file_tty(filp); |
2141 | struct tty_ldisc *ldisc; | ||
2141 | unsigned long flags; | 2142 | unsigned long flags; |
2142 | int retval = 0; | 2143 | int retval = 0; |
2143 | 2144 | ||
@@ -2148,11 +2149,17 @@ static int __tty_fasync(int fd, struct file *filp, int on) | |||
2148 | if (retval <= 0) | 2149 | if (retval <= 0) |
2149 | goto out; | 2150 | goto out; |
2150 | 2151 | ||
2152 | ldisc = tty_ldisc_ref(tty); | ||
2153 | if (ldisc) { | ||
2154 | if (ldisc->ops->fasync) | ||
2155 | ldisc->ops->fasync(tty, on); | ||
2156 | tty_ldisc_deref(ldisc); | ||
2157 | } | ||
2158 | |||
2151 | if (on) { | 2159 | if (on) { |
2152 | enum pid_type type; | 2160 | enum pid_type type; |
2153 | struct pid *pid; | 2161 | struct pid *pid; |
2154 | if (!waitqueue_active(&tty->read_wait)) | 2162 | |
2155 | tty->minimum_to_wake = 1; | ||
2156 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 2163 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
2157 | if (tty->pgrp) { | 2164 | if (tty->pgrp) { |
2158 | pid = tty->pgrp; | 2165 | pid = tty->pgrp; |
@@ -2165,13 +2172,7 @@ static int __tty_fasync(int fd, struct file *filp, int on) | |||
2165 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 2172 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
2166 | retval = __f_setown(filp, pid, type, 0); | 2173 | retval = __f_setown(filp, pid, type, 0); |
2167 | put_pid(pid); | 2174 | put_pid(pid); |
2168 | if (retval) | ||
2169 | goto out; | ||
2170 | } else { | ||
2171 | if (!tty->fasync && !waitqueue_active(&tty->read_wait)) | ||
2172 | tty->minimum_to_wake = N_TTY_BUF_SIZE; | ||
2173 | } | 2175 | } |
2174 | retval = 0; | ||
2175 | out: | 2176 | out: |
2176 | return retval; | 2177 | return retval; |
2177 | } | 2178 | } |