Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7896f30d authored by Peter Hurley's avatar Peter Hurley Committed by Greg Kroah-Hartman
Browse files

tty: Refactor tty_ldisc_reinit() for reuse



At tty hangup, the line discipline instance is reinitialized by
closing the current ldisc instance and opening a new instance.
This operation is complicated by error recovery: if the attempt
to reinit the current line discipline fails, the line discipline
is reset to N_TTY (which should not but can fail).

Re-purpose tty_ldisc_reinit() to return a valid, open line discipline
instance, or otherwise, an error.

Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c12da96f
Loading
Loading
Loading
Loading
+31 −22
Original line number Diff line number Diff line
@@ -641,26 +641,41 @@ static void tty_reset_termios(struct tty_struct *tty)
 *	@tty: tty to reinit
 *	@disc: line discipline to reinitialize
 *
 *	Switch the tty to a line discipline and leave the ldisc
 *	state closed
 *	Completely reinitialize the line discipline state, by closing the
 *	current instance and opening a new instance. If an error occurs opening
 *	the new non-N_TTY instance, the instance is dropped and tty->ldisc reset
 *	to NULL. The caller can then retry with N_TTY instead.
 *
 *	Returns 0 if successful, otherwise error code < 0
 */

static int tty_ldisc_reinit(struct tty_struct *tty, int disc)
{
	struct tty_ldisc *ld = tty_ldisc_get(tty, disc);
	struct tty_ldisc *ld;
	int retval;

	if (IS_ERR(ld))
		return -1;
	ld = tty_ldisc_get(tty, disc);
	if (IS_ERR(ld)) {
		BUG_ON(disc == N_TTY);
		return PTR_ERR(ld);
	}

	if (tty->ldisc) {
		tty_ldisc_close(tty, tty->ldisc);
		tty_ldisc_put(tty->ldisc);
	/*
	 *	Switch the line discipline back
	 */
	}

	/* switch the line discipline */
	tty->ldisc = ld;
	tty_set_termios_ldisc(tty, disc);

	return 0;
	retval = tty_ldisc_open(tty, tty->ldisc);
	if (retval) {
		if (!WARN_ON(disc == N_TTY)) {
			tty_ldisc_put(tty->ldisc);
			tty->ldisc = NULL;
		}
	}
	return retval;
}

/**
@@ -716,19 +731,13 @@ void tty_ldisc_hangup(struct tty_struct *tty)
		   reopen a new ldisc. We could defer the reopen to the next
		   open but it means auditing a lot of other paths so this is
		   a FIXME */
		if (reset == 0) {
		if (reset == 0)
			err = tty_ldisc_reinit(tty, tty->termios.c_line);

			if (!tty_ldisc_reinit(tty, tty->termios.c_line))
				err = tty_ldisc_open(tty, tty->ldisc);
			else
				err = 1;
		}
		/* If the re-open fails or we reset then go to N_TTY. The
		   N_TTY open cannot fail */
		if (reset || err) {
			BUG_ON(tty_ldisc_reinit(tty, N_TTY));
			WARN_ON(tty_ldisc_open(tty, tty->ldisc));
		}
		if (reset || err < 0)
			tty_ldisc_reinit(tty, N_TTY);
	}
	tty_ldisc_unlock(tty);
	if (reset)