Commit 102dc8aa authored by Jiri Slaby (SUSE)'s avatar Jiri Slaby (SUSE) Committed by Greg Kroah-Hartman
Browse files

tty: n_tty: move canon handling to a separate function



n_tty_receive_char_special() is already complicated enough. Split the
canon handling to a separate function: n_tty_receive_char_canon().

Signed-off-by: default avatar"Jiri Slaby (SUSE)" <jirislaby@kernel.org>
Link: https://lore.kernel.org/r/20230827074147.2287-8-jirislaby@kernel.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 819287f0
Loading
Loading
Loading
Loading
+87 −71
Original line number Diff line number Diff line
@@ -1262,47 +1262,18 @@ static bool n_tty_receive_char_flow_ctrl(struct tty_struct *tty, unsigned char c
	return true;
}

static void n_tty_receive_char_special(struct tty_struct *tty, unsigned char c,
				       bool lookahead_done)
static bool n_tty_receive_char_canon(struct tty_struct *tty, u8 c)
{
	struct n_tty_data *ldata = tty->disc_data;

	if (I_IXON(tty) && n_tty_receive_char_flow_ctrl(tty, c, lookahead_done))
		return;

	if (L_ISIG(tty)) {
		if (c == INTR_CHAR(tty)) {
			n_tty_receive_signal_char(tty, SIGINT, c);
			return;
		} else if (c == QUIT_CHAR(tty)) {
			n_tty_receive_signal_char(tty, SIGQUIT, c);
			return;
		} else if (c == SUSP_CHAR(tty)) {
			n_tty_receive_signal_char(tty, SIGTSTP, c);
			return;
		}
	}

	if (tty->flow.stopped && !tty->flow.tco_stopped && I_IXON(tty) && I_IXANY(tty)) {
		start_tty(tty);
		process_echoes(tty);
	}

	if (c == '\r') {
		if (I_IGNCR(tty))
			return;
		if (I_ICRNL(tty))
			c = '\n';
	} else if (c == '\n' && I_INLCR(tty))
		c = '\r';

	if (ldata->icanon) {
	if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) ||
	    (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) {
		eraser(c, tty);
		commit_echoes(tty);
			return;

		return true;
	}

	if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) {
		ldata->lnext = 1;
		if (L_ECHO(tty)) {
@@ -1313,8 +1284,10 @@ static void n_tty_receive_char_special(struct tty_struct *tty, unsigned char c,
				commit_echoes(tty);
			}
		}
			return;

		return true;
	}

	if (c == REPRINT_CHAR(tty) && L_ECHO(tty) && L_IEXTEN(tty)) {
		size_t tail = ldata->canon_head;

@@ -1326,8 +1299,10 @@ static void n_tty_receive_char_special(struct tty_struct *tty, unsigned char c,
			tail++;
		}
		commit_echoes(tty);
			return;

		return true;
	}

	if (c == '\n') {
		if (L_ECHO(tty) || L_ECHONL(tty)) {
			echo_char_raw('\n', ldata);
@@ -1335,10 +1310,12 @@ static void n_tty_receive_char_special(struct tty_struct *tty, unsigned char c,
		}
		goto handle_newline;
	}

	if (c == EOF_CHAR(tty)) {
		c = __DISABLED_CHAR;
		goto handle_newline;
	}

	if ((c == EOL_CHAR(tty)) ||
	    (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) {
		/*
@@ -1364,10 +1341,49 @@ static void n_tty_receive_char_special(struct tty_struct *tty, unsigned char c,
		smp_store_release(&ldata->canon_head, ldata->read_head);
		kill_fasync(&tty->fasync, SIGIO, POLL_IN);
		wake_up_interruptible_poll(&tty->read_wait, EPOLLIN | EPOLLRDNORM);
		return true;
	}

	return false;
}

static void n_tty_receive_char_special(struct tty_struct *tty, unsigned char c,
				       bool lookahead_done)
{
	struct n_tty_data *ldata = tty->disc_data;

	if (I_IXON(tty) && n_tty_receive_char_flow_ctrl(tty, c, lookahead_done))
		return;

	if (L_ISIG(tty)) {
		if (c == INTR_CHAR(tty)) {
			n_tty_receive_signal_char(tty, SIGINT, c);
			return;
		} else if (c == QUIT_CHAR(tty)) {
			n_tty_receive_signal_char(tty, SIGQUIT, c);
			return;
		} else if (c == SUSP_CHAR(tty)) {
			n_tty_receive_signal_char(tty, SIGTSTP, c);
			return;
		}
	}

	if (tty->flow.stopped && !tty->flow.tco_stopped && I_IXON(tty) && I_IXANY(tty)) {
		start_tty(tty);
		process_echoes(tty);
	}

	if (c == '\r') {
		if (I_IGNCR(tty))
			return;
		if (I_ICRNL(tty))
			c = '\n';
	} else if (c == '\n' && I_INLCR(tty))
		c = '\r';

	if (ldata->icanon && n_tty_receive_char_canon(tty, c))
		return;

	if (L_ECHO(tty)) {
		finish_erasing(ldata);
		if (c == '\n')