tty: Handle NULL tty->ldisc
In preparation of destroying line discipline on hangup, fix ldisc core operations to properly handle when the tty's ldisc is NULL. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
e55afd11a4
commit
a570a49abd
1 changed files with 12 additions and 4 deletions
|
@ -269,7 +269,8 @@ const struct file_operations tty_ldiscs_proc_fops = {
|
||||||
struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
|
struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
|
||||||
{
|
{
|
||||||
ldsem_down_read(&tty->ldisc_sem, MAX_SCHEDULE_TIMEOUT);
|
ldsem_down_read(&tty->ldisc_sem, MAX_SCHEDULE_TIMEOUT);
|
||||||
WARN_ON(!tty->ldisc);
|
if (!tty->ldisc)
|
||||||
|
ldsem_up_read(&tty->ldisc_sem);
|
||||||
return tty->ldisc;
|
return tty->ldisc;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
|
EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
|
||||||
|
@ -460,7 +461,7 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
|
||||||
if (ret)
|
if (ret)
|
||||||
clear_bit(TTY_LDISC_OPEN, &tty->flags);
|
clear_bit(TTY_LDISC_OPEN, &tty->flags);
|
||||||
|
|
||||||
tty_ldisc_debug(tty, "%p: opened\n", tty->ldisc);
|
tty_ldisc_debug(tty, "%p: opened\n", ld);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -481,7 +482,7 @@ static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)
|
||||||
clear_bit(TTY_LDISC_OPEN, &tty->flags);
|
clear_bit(TTY_LDISC_OPEN, &tty->flags);
|
||||||
if (ld->ops->close)
|
if (ld->ops->close)
|
||||||
ld->ops->close(tty);
|
ld->ops->close(tty);
|
||||||
tty_ldisc_debug(tty, "%p: closed\n", tty->ldisc);
|
tty_ldisc_debug(tty, "%p: closed\n", ld);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -544,6 +545,11 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
|
||||||
if (retval)
|
if (retval)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
if (!tty->ldisc) {
|
||||||
|
retval = -EIO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check the no-op case */
|
/* Check the no-op case */
|
||||||
if (tty->ldisc->ops->num == ldisc)
|
if (tty->ldisc->ops->num == ldisc)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -659,7 +665,7 @@ void tty_ldisc_hangup(struct tty_struct *tty)
|
||||||
int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS;
|
int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
tty_ldisc_debug(tty, "%p: closing\n", tty->ldisc);
|
tty_ldisc_debug(tty, "%p: hangup\n", tty->ldisc);
|
||||||
|
|
||||||
ld = tty_ldisc_ref(tty);
|
ld = tty_ldisc_ref(tty);
|
||||||
if (ld != NULL) {
|
if (ld != NULL) {
|
||||||
|
@ -743,6 +749,8 @@ int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
|
||||||
|
|
||||||
static void tty_ldisc_kill(struct tty_struct *tty)
|
static void tty_ldisc_kill(struct tty_struct *tty)
|
||||||
{
|
{
|
||||||
|
if (!tty->ldisc)
|
||||||
|
return;
|
||||||
/*
|
/*
|
||||||
* Now kill off the ldisc
|
* Now kill off the ldisc
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue