mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-13 22:59:31 +02:00
Fix simple_prompt() to disable echo on Windows when stdin != terminal.
If echo = false, simple_prompt() is supposed to prevent echoing the
input (for password input). However, the Windows implementation applied
the mode change to STD_INPUT_HANDLE. That would not have the desired
effect if stdin isn't actually the terminal, for instance if the user
is piping something into psql. Fix it to apply the mode change to
the correct input file, so that passwords do not echo in such cases.
In passing, shorten and de-uglify this code by using #elif rather than
an #if nest and removing some duplicated code.
Back-patch to all supported versions. To simplify that, also back-patch
the portions of commit 9daec77e1
that got rid of an unnecessary
malloc/free in the same area.
Matthew Stickney (cosmetic changes by me)
Discussion: https://postgr.es/m/502a1fff-862b-da52-1031-f68df6ed5a2d@gmail.com
This commit is contained in:
parent
588edd83e5
commit
bbaf75ee0c
@ -42,14 +42,12 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
|
|||||||
FILE *termin,
|
FILE *termin,
|
||||||
*termout;
|
*termout;
|
||||||
|
|
||||||
#ifdef HAVE_TERMIOS_H
|
#if defined(HAVE_TERMIOS_H)
|
||||||
struct termios t_orig,
|
struct termios t_orig,
|
||||||
t;
|
t;
|
||||||
#else
|
#elif defined(WIN32)
|
||||||
#ifdef WIN32
|
|
||||||
HANDLE t = NULL;
|
HANDLE t = NULL;
|
||||||
LPDWORD t_orig = NULL;
|
DWORD t_orig = 0;
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
destination = (char *) malloc(maxlen + 1);
|
destination = (char *) malloc(maxlen + 1);
|
||||||
@ -72,8 +70,11 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
|
|||||||
*
|
*
|
||||||
* XXX fgets() still receives text in the console's input code page. This
|
* XXX fgets() still receives text in the console's input code page. This
|
||||||
* makes non-ASCII credentials unportable.
|
* 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+");
|
termout = fopen("CONOUT$", "w+");
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@ -105,30 +106,25 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
|
|||||||
termout = stderr;
|
termout = stderr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_TERMIOS_H
|
|
||||||
if (!echo)
|
if (!echo)
|
||||||
{
|
{
|
||||||
|
#if defined(HAVE_TERMIOS_H)
|
||||||
|
/* disable echo via tcgetattr/tcsetattr */
|
||||||
tcgetattr(fileno(termin), &t);
|
tcgetattr(fileno(termin), &t);
|
||||||
t_orig = t;
|
t_orig = t;
|
||||||
t.c_lflag &= ~ECHO;
|
t.c_lflag &= ~ECHO;
|
||||||
tcsetattr(fileno(termin), TCSAFLUSH, &t);
|
tcsetattr(fileno(termin), TCSAFLUSH, &t);
|
||||||
}
|
#elif defined(WIN32)
|
||||||
#else
|
/* need the file's HANDLE to turn echo off */
|
||||||
#ifdef WIN32
|
t = (HANDLE) _get_osfhandle(_fileno(termin));
|
||||||
if (!echo)
|
|
||||||
{
|
|
||||||
/* get a new handle to turn echo off */
|
|
||||||
t_orig = (LPDWORD) malloc(sizeof(DWORD));
|
|
||||||
t = GetStdHandle(STD_INPUT_HANDLE);
|
|
||||||
|
|
||||||
/* save the old configuration first */
|
/* save the old configuration first */
|
||||||
GetConsoleMode(t, t_orig);
|
GetConsoleMode(t, &t_orig);
|
||||||
|
|
||||||
/* set to the new mode */
|
/* set to the new mode */
|
||||||
SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
|
SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (prompt)
|
if (prompt)
|
||||||
{
|
{
|
||||||
@ -158,25 +154,19 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
|
|||||||
/* remove trailing newline */
|
/* remove trailing newline */
|
||||||
destination[length - 1] = '\0';
|
destination[length - 1] = '\0';
|
||||||
|
|
||||||
#ifdef HAVE_TERMIOS_H
|
|
||||||
if (!echo)
|
if (!echo)
|
||||||
{
|
{
|
||||||
|
/* restore previous echo behavior, then echo \n */
|
||||||
|
#if defined(HAVE_TERMIOS_H)
|
||||||
tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
|
tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
|
||||||
fputs("\n", termout);
|
fputs("\n", termout);
|
||||||
fflush(termout);
|
fflush(termout);
|
||||||
}
|
#elif defined(WIN32)
|
||||||
#else
|
SetConsoleMode(t, t_orig);
|
||||||
#ifdef WIN32
|
|
||||||
if (!echo)
|
|
||||||
{
|
|
||||||
/* reset to the original console mode */
|
|
||||||
SetConsoleMode(t, *t_orig);
|
|
||||||
fputs("\n", termout);
|
fputs("\n", termout);
|
||||||
fflush(termout);
|
fflush(termout);
|
||||||
free(t_orig);
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (termin != stdin)
|
if (termin != stdin)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user