]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
ptyfwd: save the last character before the escape sequence
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 18 Dec 2024 02:10:47 +0000 (11:10 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 18 Dec 2024 10:55:46 +0000 (19:55 +0900)
If we write e.g. a line break and CSI sequence, then it is not necessary
to write another line break on exit.

src/shared/ptyfwd.c

index f41b525b471146c9ccc68075b705609a1bebb533..9fc8e30b0c0a27a0fee829fb72befb5cfc49d9bc 100644 (file)
@@ -85,6 +85,7 @@ struct PTYForward {
 
         bool last_char_set:1;
         char last_char;
+        char last_char_safe;
 
         char in_buffer[LINE_MAX], *out_buffer;
         size_t out_buffer_size;
@@ -439,8 +440,11 @@ static int pty_forward_ansi_process(PTYForward *f, size_t offset) {
                                 if (r < 0)
                                         return r;
                                 i += r;
+                                f->last_char_safe = c;
                         } else if (c == 0x1B) /* ESC */
                                 f->ansi_color_state = ANSI_COLOR_STATE_ESC;
+                        else if (!char_is_cc(c))
+                                f->last_char_safe = c;
                         break;
 
                 case ANSI_COLOR_STATE_ESC:
@@ -705,8 +709,15 @@ static int do_shovel(PTYForward *f) {
 
                         } else {
 
-                                if (k > 0) {
-                                        f->last_char = f->out_buffer[k-1];
+                                if (k > 0 && f->last_char_safe != '\0') {
+                                        if ((size_t) k == f->out_buffer_write_len)
+                                                /* If we wrote all, then save the last safe character. */
+                                                f->last_char = f->last_char_safe;
+                                        else
+                                                /* If we wrote partially, then tentatively save the last written character.
+                                                 * Hopefully, we will write more in the next loop. */
+                                                f->last_char = f->out_buffer[k-1];
+
                                         f->last_char_set = true;
                                 }