|
@@ -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
|