aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/port/sprompt.c40
1 files changed, 16 insertions, 24 deletions
diff --git a/src/port/sprompt.c b/src/port/sprompt.c
index 47cd9781fd2..f98eb0b6b1f 100644
--- a/src/port/sprompt.c
+++ b/src/port/sprompt.c
@@ -40,15 +40,13 @@ simple_prompt(const char *prompt, char *destination, size_t destlen, bool echo)
FILE *termin,
*termout;
-#ifdef HAVE_TERMIOS_H
+#if defined(HAVE_TERMIOS_H)
struct termios t_orig,
t;
-#else
-#ifdef WIN32
+#elif defined(WIN32)
HANDLE t = NULL;
DWORD t_orig = 0;
#endif
-#endif
#ifdef WIN32
@@ -66,8 +64,11 @@ simple_prompt(const char *prompt, char *destination, size_t destlen, bool echo)
*
* XXX fgets() still receives text in the console's input code page. This
* makes non-ASCII credentials unportable.
+ *
+ * Unintuitively, we also open termin in mode "w+", even though we only
+ * read it; that's needed for SetConsoleMode() to succeed.
*/
- termin = fopen("CONIN$", "r");
+ termin = fopen("CONIN$", "w+");
termout = fopen("CONOUT$", "w+");
#else
@@ -99,29 +100,25 @@ simple_prompt(const char *prompt, char *destination, size_t destlen, bool echo)
termout = stderr;
}
-#ifdef HAVE_TERMIOS_H
if (!echo)
{
+#if defined(HAVE_TERMIOS_H)
+ /* disable echo via tcgetattr/tcsetattr */
tcgetattr(fileno(termin), &t);
t_orig = t;
t.c_lflag &= ~ECHO;
tcsetattr(fileno(termin), TCSAFLUSH, &t);
- }
-#else
-#ifdef WIN32
- if (!echo)
- {
- /* get a new handle to turn echo off */
- t = GetStdHandle(STD_INPUT_HANDLE);
+#elif defined(WIN32)
+ /* need the file's HANDLE to turn echo off */
+ t = (HANDLE) _get_osfhandle(_fileno(termin));
/* save the old configuration first */
GetConsoleMode(t, &t_orig);
/* set to the new mode */
SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
- }
-#endif
#endif
+ }
if (prompt)
{
@@ -151,24 +148,19 @@ simple_prompt(const char *prompt, char *destination, size_t destlen, bool echo)
/* remove trailing newline */
destination[length - 1] = '\0';
-#ifdef HAVE_TERMIOS_H
if (!echo)
{
+ /* restore previous echo behavior, then echo \n */
+#if defined(HAVE_TERMIOS_H)
tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
fputs("\n", termout);
fflush(termout);
- }
-#else
-#ifdef WIN32
- if (!echo)
- {
- /* reset to the original console mode */
+#elif defined(WIN32)
SetConsoleMode(t, t_orig);
fputs("\n", termout);
fflush(termout);
- }
-#endif
#endif
+ }
if (termin != stdin)
{