Commit c6d31b27 authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-4021 : Enable Ctrl-C handler when reading password, on Windows.

Prior to this patch, _getch() was used to read password input from console. getch() has a property that it reads Ctrl-C as character with ASCII code 0x03, and disregards Ctrl-C handler for  current process. 
The fix is to use ReadConsole() API instead of getch() , after setting console mode to ENABLE_PROCESSED_INPUT - this mode allows current process to handle Ctrl-C events.
parent e03e9aab
...@@ -62,13 +62,34 @@ ...@@ -62,13 +62,34 @@
/* were just going to fake it here and get input from the keyboard */ /* were just going to fake it here and get input from the keyboard */
void get_tty_password_buff(const char *opt_message, char *to, size_t length) void get_tty_password_buff(const char *opt_message, char *to, size_t length)
{ {
HANDLE consoleinput;
DWORD oldstate;
char *pos=to,*end=to+length-1; char *pos=to,*end=to+length-1;
int i=0; int i=0;
consoleinput= GetStdHandle(STD_INPUT_HANDLE);
if (!consoleinput)
{
/* This is a GUI application or service without console input, bail out. */
*to= 0;
return;
}
_cputs(opt_message ? opt_message : "Enter password: "); _cputs(opt_message ? opt_message : "Enter password: ");
/*
Switch to raw mode (no line input, no echo input).
Allow Ctrl-C handler with ENABLE_PROCESSED_INPUT.
*/
GetConsoleMode(consoleinput, &oldstate);
SetConsoleMode(consoleinput, ENABLE_PROCESSED_INPUT);
for (;;) for (;;)
{ {
int tmp; char tmp;
tmp=_getch(); DWORD chars_read;
if (!ReadConsole(consoleinput, &tmp, 1, &chars_read, NULL))
break;
if (chars_read == 0)
break;
if (tmp == '\b' || tmp == 127) if (tmp == '\b' || tmp == 127)
{ {
if (pos != to) if (pos != to)
...@@ -78,13 +99,15 @@ void get_tty_password_buff(const char *opt_message, char *to, size_t length) ...@@ -78,13 +99,15 @@ void get_tty_password_buff(const char *opt_message, char *to, size_t length)
continue; continue;
} }
} }
if (tmp == -1 || tmp == '\n' || tmp == '\r' || tmp == 3) if (tmp == '\n' || tmp == '\r')
break; break;
if (iscntrl(tmp) || pos == end) if (iscntrl(tmp) || pos == end)
continue; continue;
_cputs("*"); _cputs("*");
*(pos++) = (char)tmp; *(pos++) = tmp;
} }
/* Reset console mode after password input. */
SetConsoleMode(consoleinput, oldstate);
*pos=0; *pos=0;
_cputs("\n"); _cputs("\n");
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment