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
*
* 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
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)
{
/* 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)
{