зеркало из https://github.com/microsoft/git.git
mingw: reuse tty-version of git_terminal_prompt
The getpass-implementation we use on Windows isn't at all ideal; it works in raw-mode (as opposed to cooked mode), and as a result does not deal correcly with deletion, arrow-keys etc. Instead, use cooked mode to read a line at the time, allowing the C run-time to process the input properly. Since we set files to be opened in binary-mode by default on Windows, introduce a FORCE_TEXT macro that expands to the "t" modifier that forces the terminal to be opened in text-mode so we do not have to deal with CRLF issues. Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
67fe735653
Коммит
afb43561b8
|
@ -3,8 +3,22 @@
|
|||
#include "sigchain.h"
|
||||
#include "strbuf.h"
|
||||
|
||||
#if defined(HAVE_DEV_TTY) || defined(WIN32)
|
||||
|
||||
static void restore_term(void);
|
||||
|
||||
static void restore_term_on_signal(int sig)
|
||||
{
|
||||
restore_term();
|
||||
sigchain_pop(sig);
|
||||
raise(sig);
|
||||
}
|
||||
|
||||
#ifdef HAVE_DEV_TTY
|
||||
|
||||
#define INPUT_PATH "/dev/tty"
|
||||
#define OUTPUT_PATH "/dev/tty"
|
||||
|
||||
static int term_fd = -1;
|
||||
static struct termios old_term;
|
||||
|
||||
|
@ -18,13 +32,6 @@ static void restore_term(void)
|
|||
term_fd = -1;
|
||||
}
|
||||
|
||||
static void restore_term_on_signal(int sig)
|
||||
{
|
||||
restore_term();
|
||||
sigchain_pop(sig);
|
||||
raise(sig);
|
||||
}
|
||||
|
||||
static int disable_echo(void)
|
||||
{
|
||||
struct termios t;
|
||||
|
@ -46,17 +53,61 @@ error:
|
|||
return -1;
|
||||
}
|
||||
|
||||
#elif defined(WIN32)
|
||||
|
||||
#define INPUT_PATH "CONIN$"
|
||||
#define OUTPUT_PATH "CONOUT$"
|
||||
#define FORCE_TEXT "t"
|
||||
|
||||
static HANDLE hconin = INVALID_HANDLE_VALUE;
|
||||
static DWORD cmode;
|
||||
|
||||
static void restore_term(void)
|
||||
{
|
||||
if (hconin == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
||||
SetConsoleMode(hconin, cmode);
|
||||
CloseHandle(hconin);
|
||||
hconin = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
static int disable_echo(void)
|
||||
{
|
||||
hconin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hconin == INVALID_HANDLE_VALUE)
|
||||
return -1;
|
||||
|
||||
GetConsoleMode(hconin, &cmode);
|
||||
sigchain_push_common(restore_term_on_signal);
|
||||
if (!SetConsoleMode(hconin, cmode & (~ENABLE_ECHO_INPUT))) {
|
||||
CloseHandle(hconin);
|
||||
hconin = INVALID_HANDLE_VALUE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef FORCE_TEXT
|
||||
#define FORCE_TEXT
|
||||
#endif
|
||||
|
||||
char *git_terminal_prompt(const char *prompt, int echo)
|
||||
{
|
||||
static struct strbuf buf = STRBUF_INIT;
|
||||
int r;
|
||||
FILE *input_fh, *output_fh;
|
||||
|
||||
input_fh = fopen("/dev/tty", "r");
|
||||
input_fh = fopen(INPUT_PATH, "r" FORCE_TEXT);
|
||||
if (!input_fh)
|
||||
return NULL;
|
||||
|
||||
output_fh = fopen("/dev/tty", "w");
|
||||
output_fh = fopen(OUTPUT_PATH, "w" FORCE_TEXT);
|
||||
if (!output_fh) {
|
||||
fclose(input_fh);
|
||||
return NULL;
|
||||
|
|
Загрузка…
Ссылка в новой задаче