Right now the output from the microcom program itself is buffered and
not shown to the user as soon as possible, resulting in strange
artifacts like:
  * Start of program "Escape character is ..." prompt is not shown until
    the user first hit the escape character.
  * "Filename: " prompt is not visible to the user.

This patch changes buffered write to stdout to unbuffered write.
Also changes the "paste file" command to be able to recover from open()
errors, so that errors like "file not found" don't crash the whole
console program:
  * Change xprintf to dprintf or xputs, so that written output is
    not unbuffered and immediately flushed.
  * If 'Esc' is pressed to cancel the "paste file" command, clear the
    "Filename:" prompt.
  * If "paste file" command gets an empty filename, clear the prompt.
    (same behavior as the previous case)
  * If "paste file" command failed to open() the file, just print the
    error text and then return. Don't crash.
From af3e2b003a92e4bf16261d272e0c0c4baeb880ae Mon Sep 17 00:00:00 2001
From: Yi-Yo Chiang <yochi...@google.com>
Date: Thu, 16 May 2024 18:31:41 +0800
Subject: [PATCH] microcom: Flush after writing to stdout

Right now the output from the microcom program itself is buffered and
not shown to the user as soon as possible, resulting in strange
artifacts like:
  * Start of program "Escape character is ..." prompt is not shown until
    the user first hit the escape character.
  * "Filename: " prompt is not visible to the user.

This patch changes buffered write to stdout to unbuffered write.
Also changes the "paste file" command to be able to recover from open()
errors, so that errors like "file not found" don't crash the whole
console program:
  * Change xprintf to dprintf or xputs, so that written output is
    not unbuffered and immediately flushed.
  * If 'Esc' is pressed to cancel the "paste file" command, clear the
    "Filename:" prompt.
  * If "paste file" command gets an empty filename, clear the prompt.
    (same behavior as the previous case)
  * If "paste file" command failed to open() the file, just print the
    error text and then return. Don't crash.

Change-Id: I412a43851c5fda355622b1842212b36933878f5e
---
 toys/net/microcom.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/toys/net/microcom.c b/toys/net/microcom.c
index d805a062..553d4204 100644
--- a/toys/net/microcom.c
+++ b/toys/net/microcom.c
@@ -52,9 +52,10 @@ static void handle_esc(void)
     // TODO: tab completion!
     memset(toybuf, 0, sizeof(toybuf));
     while (1) {
-      xprintf("\r\e[2K\e[1mFilename: \e[0m%s", toybuf);
+      dprintf(1, "\r\e[2K\e[1mFilename: \e[0m%s", toybuf);
       if (read(0, &input, 1) <= 0 || input == CTRL('[')) {
-        return;
+        len = 0;
+        break;
       }
       if (input == '\r') break;
       if (input == 0x7f && len > 0) toybuf[--len] = 0;
@@ -62,10 +63,16 @@ static void handle_esc(void)
       else if (input >= ' ' && input <= 0x7f && len < sizeof(toybuf))
         toybuf[len++] = input;
     }
+    xputsn("\r\e[2K");
     toybuf[len] = 0;
     if (!len) return;
+    if ((fd = xopen(toybuf, O_RDONLY | WARN_ONLY)) < 0) {
+      // xopen() warning message ends with a LF without CR, so manually print a
+      // CR here to move the cursor back to the front.
+      xputsn("\r");
+      return;
+    }
     filename = xstrdup(toybuf);
-    fd = xopen(filename, O_RDONLY);
     size = fdlength(fd);
     // The alternative would be to just feed this fd into the usual loop,
     // so we're reading back these characters if they're being echoed, but
@@ -73,16 +80,16 @@ static void handle_esc(void)
     // is a much more convenient UI.
     while ((len = read(fd, toybuf, sizeof(toybuf))) > 0) {
       written += len;
-      xprintf("\r\e[2KPasting '%s' %lld/%lld (%lld%%)...", filename, written,
+      dprintf(1, "\r\e[2KPasting '%s' %lld/%lld (%lld%%)...", filename, written,
         size, written*100/size);
       xwrite(TT.fd, toybuf, len);
     }
     free(filename);
     close(fd);
   } else {
-    xprintf("Ignoring unknown command.");
+    xputsn("Ignoring unknown command.");
   }
-  xprintf("\r\n");
+  xputs("\r");
 }
 
 void microcom_main(void)
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog

_______________________________________________
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to