Welcome to little lamb

Code » limb » commit 43089b9

ask_password(): Write prompt to stderr (not stdout)..

author Olivier Brunel
2023-04-20 15:05:41 UTC
committer Olivier Brunel
2023-05-20 18:06:37 UTC
parent 53e5c66fd3f3d60b5392753d5d2dac9cbf768380

ask_password(): Write prompt to stderr (not stdout)..

..by default. Prefix prompt with '>' to use stdout instead. (Prefix with
a '\' to escape the first character, thusly allowing a prompt (on
stderr) starting with a '>'.

src/doc/term.h/ask_password.3.md +11 -5
src/liblimb/term.h/ask_password.c +12 -2

diff --git a/src/doc/term.h/ask_password.3.md b/src/doc/term.h/ask_password.3.md
index 0b1882d..0bbeb3f 100644
--- a/src/doc/term.h/ask_password.3.md
+++ b/src/doc/term.h/ask_password.3.md
@@ -19,8 +19,14 @@ The `ask_password`() function will read data from *stdin* up to a newline (`\n`)
 and store it into the memory area pointed by `dst`, up to `dlen` bytes.
 
 First, it will ensure input character echoing is disabled for *stdin*, then drop
-any data that might remain in `buffer_0`. If `prompt` is not NULL, it will be
-written to *stdout* before attempting to read from *stdin*.
+any data that might remain in `buffer_0`.
+
+If `prompt` is not NULL, it will be written to *stderr* before attempting to
+read from *stdin*, unless it begins with `>` in which case it is written (past
+this leading prefix) into *stdout* instead.
+
+If `prompt` begins with a backslash (`\\`) then it is skipped, to notably allow
+to use a prompt beginning with a `>` whilst remaining in *stderr*.
 
 All data read will be placed into `dst` (up to `dlen` bytes), reading stops as
 soon as a newline is read. It will /not/ write said newline in `dst` but instead
@@ -28,12 +34,12 @@ NUL-terminate the string.
 Though not checked, it is assumed that no other NUL byte will be present.
 
 Once done, character echoing is restored for *stdin*, and a newline printed on
-*stdout* if `prompt` is not NULL.
+*stderr* (or *stdout*) if `prompt` is not NULL.
 
 ! INFO:
-! The `prompt` value will be printed using the [out](3) family of functions,
+! The `prompt` value will be printed using the [err](3) family of functions,
 ! with an output level of *OLVL_NORMAL*, and as such written not only to
-! `obuffer_1` but duplicated on any extra buffers as well.
+! `obuffer_2` (or `obuffer_1`) but duplicated on any extra buffers as well.
 ! Refer to [outpout.h](0) for more.
 
 # RETURN VALUE
diff --git a/src/liblimb/term.h/ask_password.c b/src/liblimb/term.h/ask_password.c
index 93d9287..8a2afe6 100644
--- a/src/liblimb/term.h/ask_password.c
+++ b/src/liblimb/term.h/ask_password.c
@@ -17,7 +17,17 @@ ask_password(char *dst, size_t dlen, const char *prompt)
     /* drop any unread/buffered input */
     buffer_rseek(buffer_0, buffer_len(buffer_0));
 
-    if (prompt) add(prompt, PUTMSG_FLUSH);
+    /* prompt: if prefixed with '>' then use stderr instead of stdout.
+     * Also a leading '\\' is skipped, to allow to start a prompt with a '>'
+     * still on stderr */
+    obuffer_putmsgfn putmsg = err_putmsg;
+    if (prompt) {
+        if (*prompt == '>')
+            putmsg = out_putmsg;
+        if (*prompt == '>' || *prompt == '\\')
+            ++prompt;
+        putmsg(OLVL_NORMAL, (const char *[]) { prompt, PUTMSG_FLUSH }, 2);
+    }
 
     size_t plen = 0;
     int r = buffer_getuptoc(buffer_0, dst, dlen, '\n', &plen);
@@ -30,7 +40,7 @@ ask_password(char *dst, size_t dlen, const char *prompt)
     }
 
     /* if we put up a prompt, add a newline */
-    if (prompt) out(NULL);
+    if (prompt) putmsg(OLVL_NORMAL, (const char *[]) { "\n", PUTMSG_FLUSH }, 2);
     /* restore echo if we did indeed turn it off */
     if (echo) {
         int e = errno;