summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/tty_io.c29
1 files changed, 10 insertions, 19 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index adbd9ac..ffa31c6 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -1755,7 +1755,7 @@ int tty_release(struct inode *inode, struct file *filp)
{
struct tty_struct *tty = file_tty(filp);
struct tty_struct *o_tty;
- int pty_master, tty_closing, o_tty_closing, do_sleep;
+ int pty_master, do_sleep, final;
int idx;
char buf[64];
@@ -1797,18 +1797,15 @@ int tty_release(struct inode *inode, struct file *filp)
* The test for the o_tty closing is necessary, since the master and
* slave sides may close in any order. If the slave side closes out
* first, its count will be one, since the master side holds an open.
- * Thus this test wouldn't be triggered at the time the slave closes,
+ * Thus this test wouldn't be triggered at the time the slave closed,
* so we do it now.
*/
tty_lock_pair(tty, o_tty);
while (1) {
- tty_closing = tty->count <= 1;
- o_tty_closing = o_tty &&
- (o_tty->count <= (pty_master ? 1 : 0));
do_sleep = 0;
- if (tty_closing) {
+ if (tty->count <= 1) {
if (waitqueue_active(&tty->read_wait)) {
wake_up_poll(&tty->read_wait, POLLIN);
do_sleep++;
@@ -1818,7 +1815,7 @@ int tty_release(struct inode *inode, struct file *filp)
do_sleep++;
}
}
- if (o_tty_closing) {
+ if (pty_master && o_tty->count <= 1) {
if (waitqueue_active(&o_tty->read_wait)) {
wake_up_poll(&o_tty->read_wait, POLLIN);
do_sleep++;
@@ -1836,14 +1833,6 @@ int tty_release(struct inode *inode, struct file *filp)
schedule();
}
- /*
- * The closing flags are now consistent with the open counts on
- * both sides, and we've completed the last operation that could
- * block, so it's safe to proceed with closing.
- *
- * We must *not* drop the tty_mutex until we ensure that a further
- * entry into tty_open can not pick up this tty.
- */
if (pty_master) {
if (--o_tty->count < 0) {
printk(KERN_WARNING "%s: bad pty slave count (%d) for %s\n",
@@ -1875,20 +1864,22 @@ int tty_release(struct inode *inode, struct file *filp)
* processes that still think tty or o_tty is their controlling
* tty.
*/
- if (tty_closing || o_tty_closing) {
+ if (!tty->count) {
read_lock(&tasklist_lock);
session_clear_tty(tty->session);
- if (o_tty)
+ if (pty_master)
session_clear_tty(o_tty->session);
read_unlock(&tasklist_lock);
}
+ /* check whether both sides are closing ... */
+ final = !tty->count && !(pty_master && o_tty->count);
+
tty_unlock_pair(tty, o_tty);
/* At this point, the tty->count == 0 should ensure a dead tty
cannot be re-opened by a racing opener */
- /* check whether both sides are closing ... */
- if (!tty_closing || (o_tty && !o_tty_closing))
+ if (!final)
return 0;
#ifdef TTY_DEBUG_HANGUP