]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared/ask-password-api: backspace all chars at once 13022/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 11 Jul 2019 07:00:49 +0000 (09:00 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 11 Jul 2019 22:35:05 +0000 (00:35 +0200)
We'd call loop_write() separately for each char. Let's be nice to
serial console users, and write the full string in one go.

Coverity was complaining that we're not checking the return value
from loop_write(). Rework the code a bit and add voidify.
CID#1402323.

src/shared/ask-password-api.c

index 00c41a0382082bc585e14698a9a61636846669b7..c41fa2dea6d8102f908349d416d57066b65d3242 100644 (file)
@@ -178,37 +178,37 @@ static int ask_password_keyring(const char *keyname, AskPasswordFlags flags, cha
         return retrieve_key(serial, ret);
 }
 
-static void backspace_chars(int ttyfd, size_t p) {
-
+static int backspace_chars(int ttyfd, size_t p) {
         if (ttyfd < 0)
-                return;
+                return 0;
 
-        while (p > 0) {
-                p--;
+        _cleanup_free_ char *buf = malloc_multiply(3, p);
+        if (!buf)
+                return log_oom();
 
-                loop_write(ttyfd, "\b \b", 3, false);
-        }
-}
+        for (size_t i = 0; i < p; i++)
+                memcpy(buf + 3 * i, "\b \b", 3);
 
-static void backspace_string(int ttyfd, const char *str) {
-        size_t m;
+        return loop_write(ttyfd, buf, 3*p, false);
+}
 
+static int backspace_string(int ttyfd, const char *str) {
         assert(str);
 
-        if (ttyfd < 0)
-                return;
-
         /* Backspaces through enough characters to entirely undo printing of the specified string. */
 
-        m = utf8_n_codepoints(str);
+        if (ttyfd < 0)
+                return 0;
+
+        size_t m = utf8_n_codepoints(str);
         if (m == (size_t) -1)
-                m = strlen(str); /* Not a valid UTF-8 string? If so, let's backspace the number of bytes output. Most
-                                  * likely this happened because we are not in an UTF-8 locale, and in that case that
-                                  * is the correct thing to do. And even if it's not, terminals tend to stop
-                                  * backspacing at the leftmost column, hence backspacing too much should be mostly
-                                  * OK. */
+                m = strlen(str); /* Not a valid UTF-8 string? If so, let's backspace the number of bytes
+                                  * output. Most likely this happened because we are not in an UTF-8 locale,
+                                  * and in that case that is the correct thing to do. And even if it's not,
+                                  * terminals tend to stop backspacing at the leftmost column, hence
+                                  * backspacing too much should be mostly OK. */
 
-        backspace_chars(ttyfd, m);
+        return backspace_chars(ttyfd, m);
 }
 
 int ask_password_tty(
@@ -374,7 +374,7 @@ int ask_password_tty(
                 if (c == 21) { /* C-u */
 
                         if (!(flags & ASK_PASSWORD_SILENT))
-                                backspace_string(ttyfd, passphrase);
+                                (void) backspace_string(ttyfd, passphrase);
 
                         explicit_bzero_safe(passphrase, sizeof(passphrase));
                         p = codepoint = 0;
@@ -385,7 +385,7 @@ int ask_password_tty(
                                 size_t q;
 
                                 if (!(flags & ASK_PASSWORD_SILENT))
-                                        backspace_chars(ttyfd, 1);
+                                        (void) backspace_chars(ttyfd, 1);
 
                                 /* Remove a full UTF-8 codepoint from the end. For that, figure out where the
                                  * last one begins */
@@ -423,7 +423,7 @@ int ask_password_tty(
 
                 } else if (c == '\t' && !(flags & ASK_PASSWORD_SILENT)) {
 
-                        backspace_string(ttyfd, passphrase);
+                        (void) backspace_string(ttyfd, passphrase);
                         flags |= ASK_PASSWORD_SILENT;
 
                         /* ... or by pressing TAB at any time. */