@@ -582,6 +582,100 @@ static ssize_t process_output_block(struct tty_struct *tty,
582
582
return i ;
583
583
}
584
584
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
+
585
679
/**
586
680
* __process_echoes - write pending echo characters
587
681
* @tty: terminal device
@@ -617,104 +711,12 @@ static size_t __process_echoes(struct tty_struct *tty)
617
711
while (MASK (ldata -> echo_commit ) != MASK (tail )) {
618
712
c = echo_buf (ldata , tail );
619
713
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 )
629
716
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 )
717
718
break ;
719
+ space = ret ;
718
720
} else {
719
721
if (O_OPOST (tty )) {
720
722
int retval = do_output_char (c , tty , space );
0 commit comments