Skip to content

Commit 2aa9185

Browse files
Jiri Slaby (SUSE)gregkh
authored andcommitted
tty: n_tty: extract ECHO_OP processing to a separate function
__process_echoes() contains ECHO_OPs processing. It is stuffed in a while loop and the whole function is barely readable. Separate it to a new function: n_tty_process_echo_ops(). Signed-off-by: "Jiri Slaby (SUSE)" <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e30364c commit 2aa9185

File tree

1 file changed

+98
-96
lines changed

1 file changed

+98
-96
lines changed

drivers/tty/n_tty.c

Lines changed: 98 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,100 @@ static ssize_t process_output_block(struct tty_struct *tty,
582582
return i;
583583
}
584584

585+
static int n_tty_process_echo_ops(struct tty_struct *tty, size_t *tail,
586+
int space)
587+
{
588+
struct n_tty_data *ldata = tty->disc_data;
589+
u8 op;
590+
591+
/*
592+
* Since add_echo_byte() is called without holding output_lock, we
593+
* might see only portion of multi-byte operation.
594+
*/
595+
if (MASK(ldata->echo_commit) == MASK(*tail + 1))
596+
return -ENODATA;
597+
598+
/*
599+
* If the buffer byte is the start of a multi-byte operation, get the
600+
* next byte, which is either the op code or a control character value.
601+
*/
602+
op = echo_buf(ldata, *tail + 1);
603+
604+
switch (op) {
605+
case ECHO_OP_ERASE_TAB: {
606+
unsigned int num_chars, num_bs;
607+
608+
if (MASK(ldata->echo_commit) == MASK(*tail + 2))
609+
return -ENODATA;
610+
611+
num_chars = echo_buf(ldata, *tail + 2);
612+
613+
/*
614+
* Determine how many columns to go back in order to erase the
615+
* tab. This depends on the number of columns used by other
616+
* characters within the tab area. If this (modulo 8) count is
617+
* from the start of input rather than from a previous tab, we
618+
* offset by canon column. Otherwise, tab spacing is normal.
619+
*/
620+
if (!(num_chars & 0x80))
621+
num_chars += ldata->canon_column;
622+
num_bs = 8 - (num_chars & 7);
623+
624+
if (num_bs > space)
625+
return -ENOSPC;
626+
627+
space -= num_bs;
628+
while (num_bs--) {
629+
tty_put_char(tty, '\b');
630+
if (ldata->column > 0)
631+
ldata->column--;
632+
}
633+
*tail += 3;
634+
break;
635+
}
636+
case ECHO_OP_SET_CANON_COL:
637+
ldata->canon_column = ldata->column;
638+
*tail += 2;
639+
break;
640+
641+
case ECHO_OP_MOVE_BACK_COL:
642+
if (ldata->column > 0)
643+
ldata->column--;
644+
*tail += 2;
645+
break;
646+
647+
case ECHO_OP_START:
648+
/* This is an escaped echo op start code */
649+
if (!space)
650+
return -ENOSPC;
651+
652+
tty_put_char(tty, ECHO_OP_START);
653+
ldata->column++;
654+
space--;
655+
*tail += 2;
656+
break;
657+
658+
default:
659+
/*
660+
* If the op is not a special byte code, it is a ctrl char
661+
* tagged to be echoed as "^X" (where X is the letter
662+
* representing the control char). Note that we must ensure
663+
* there is enough space for the whole ctrl pair.
664+
*/
665+
if (space < 2)
666+
return -ENOSPC;
667+
668+
tty_put_char(tty, '^');
669+
tty_put_char(tty, op ^ 0100);
670+
ldata->column += 2;
671+
space -= 2;
672+
*tail += 2;
673+
break;
674+
}
675+
676+
return space;
677+
}
678+
585679
/**
586680
* __process_echoes - write pending echo characters
587681
* @tty: terminal device
@@ -617,104 +711,12 @@ static size_t __process_echoes(struct tty_struct *tty)
617711
while (MASK(ldata->echo_commit) != MASK(tail)) {
618712
c = echo_buf(ldata, tail);
619713
if (c == ECHO_OP_START) {
620-
u8 op;
621-
bool space_left = true;
622-
623-
/*
624-
* Since add_echo_byte() is called without holding
625-
* output_lock, we might see only portion of multi-byte
626-
* operation.
627-
*/
628-
if (MASK(ldata->echo_commit) == MASK(tail + 1))
714+
int ret = n_tty_process_echo_ops(tty, &tail, space);
715+
if (ret == -ENODATA)
629716
goto not_yet_stored;
630-
/*
631-
* If the buffer byte is the start of a multi-byte
632-
* operation, get the next byte, which is either the
633-
* op code or a control character value.
634-
*/
635-
op = echo_buf(ldata, tail + 1);
636-
637-
switch (op) {
638-
case ECHO_OP_ERASE_TAB: {
639-
unsigned int num_chars, num_bs;
640-
641-
if (MASK(ldata->echo_commit) == MASK(tail + 2))
642-
goto not_yet_stored;
643-
num_chars = echo_buf(ldata, tail + 2);
644-
645-
/*
646-
* Determine how many columns to go back
647-
* in order to erase the tab.
648-
* This depends on the number of columns
649-
* used by other characters within the tab
650-
* area. If this (modulo 8) count is from
651-
* the start of input rather than from a
652-
* previous tab, we offset by canon column.
653-
* Otherwise, tab spacing is normal.
654-
*/
655-
if (!(num_chars & 0x80))
656-
num_chars += ldata->canon_column;
657-
num_bs = 8 - (num_chars & 7);
658-
659-
if (num_bs > space) {
660-
space_left = false;
661-
break;
662-
}
663-
space -= num_bs;
664-
while (num_bs--) {
665-
tty_put_char(tty, '\b');
666-
if (ldata->column > 0)
667-
ldata->column--;
668-
}
669-
tail += 3;
670-
break;
671-
}
672-
case ECHO_OP_SET_CANON_COL:
673-
ldata->canon_column = ldata->column;
674-
tail += 2;
675-
break;
676-
677-
case ECHO_OP_MOVE_BACK_COL:
678-
if (ldata->column > 0)
679-
ldata->column--;
680-
tail += 2;
681-
break;
682-
683-
case ECHO_OP_START:
684-
/* This is an escaped echo op start code */
685-
if (!space) {
686-
space_left = false;
687-
break;
688-
}
689-
tty_put_char(tty, ECHO_OP_START);
690-
ldata->column++;
691-
space--;
692-
tail += 2;
693-
break;
694-
695-
default:
696-
/*
697-
* If the op is not a special byte code,
698-
* it is a ctrl char tagged to be echoed
699-
* as "^X" (where X is the letter
700-
* representing the control char).
701-
* Note that we must ensure there is
702-
* enough space for the whole ctrl pair.
703-
*
704-
*/
705-
if (space < 2) {
706-
space_left = false;
707-
break;
708-
}
709-
tty_put_char(tty, '^');
710-
tty_put_char(tty, op ^ 0100);
711-
ldata->column += 2;
712-
space -= 2;
713-
tail += 2;
714-
}
715-
716-
if (!space_left)
717+
if (ret < 0)
717718
break;
719+
space = ret;
718720
} else {
719721
if (O_OPOST(tty)) {
720722
int retval = do_output_char(c, tty, space);

0 commit comments

Comments
 (0)