Skip to content

Commit a6c84ee

Browse files
committed
Merge branch 'fix-terminal-prompt'
This fixes the issue identified in #1498 where Git would not fall back to reading credentials from a Win32 Console when the credentials could not be read from the terminal via the Bash hack (that is necessary to support running in a MinTTY). Tested in a Powershell window. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2 parents 4eb979c + 325fc0a commit a6c84ee

File tree

1 file changed

+30
-9
lines changed

1 file changed

+30
-9
lines changed

compat/terminal.c

+30-9
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,26 @@ static void restore_term(void)
7777
hconin = INVALID_HANDLE_VALUE;
7878
}
7979

80-
static int disable_echo(void)
80+
static int set_echo(int echo)
8181
{
82-
hconin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
83-
FILE_SHARE_READ, NULL, OPEN_EXISTING,
84-
FILE_ATTRIBUTE_NORMAL, NULL);
82+
DWORD new_cmode;
83+
84+
if (hconin == INVALID_HANDLE_VALUE)
85+
hconin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
86+
FILE_SHARE_READ, NULL, OPEN_EXISTING,
87+
FILE_ATTRIBUTE_NORMAL, NULL);
8588
if (hconin == INVALID_HANDLE_VALUE)
8689
return -1;
8790

8891
GetConsoleMode(hconin, &cmode);
92+
new_cmode = cmode | ENABLE_LINE_INPUT;
93+
if (echo)
94+
new_cmode |= ENABLE_ECHO_INPUT;
95+
else
96+
new_cmode &= ~ENABLE_ECHO_INPUT;
97+
8998
sigchain_push_common(restore_term_on_signal);
90-
if (!SetConsoleMode(hconin, cmode & (~ENABLE_ECHO_INPUT))) {
99+
if (!SetConsoleMode(hconin, new_cmode)) {
91100
CloseHandle(hconin);
92101
hconin = INVALID_HANDLE_VALUE;
93102
return -1;
@@ -96,13 +105,20 @@ static int disable_echo(void)
96105
return 0;
97106
}
98107

108+
static int disable_echo(void)
109+
{
110+
return set_echo(0);
111+
}
112+
99113
static char *shell_prompt(const char *prompt, int echo)
100114
{
101115
const char *read_input[] = {
102116
/* Note: call 'bash' explicitly, as 'read -s' is bash-specific */
103117
"bash", "-c", echo ?
104-
"cat >/dev/tty && read -r line </dev/tty && echo \"$line\"" :
105-
"cat >/dev/tty && read -r -s line </dev/tty && echo \"$line\" && echo >/dev/tty",
118+
"test \"a$SHELL\" != \"a${SHELL%.exe}\" || exit 127; cat >/dev/tty &&"
119+
" read -r line </dev/tty && echo \"$line\"" :
120+
"test \"a$SHELL\" != \"a${SHELL%.exe}\" || exit 127; cat >/dev/tty &&"
121+
" read -r -s line </dev/tty && echo \"$line\" && echo >/dev/tty",
106122
NULL
107123
};
108124
struct child_process child = CHILD_PROCESS_INIT;
@@ -138,7 +154,10 @@ static char *shell_prompt(const char *prompt, int echo)
138154
close(child.out);
139155
code = finish_command(&child);
140156
if (code) {
141-
error("failed to execute prompt script (exit code %d)", code);
157+
if (code != 127)
158+
error("failed to execute prompt script (exit code %d)",
159+
code);
160+
142161
return NULL;
143162
}
144163

@@ -161,9 +180,11 @@ char *git_terminal_prompt(const char *prompt, int echo)
161180

162181
/* try shell_prompt first, fall back to CONIN/OUT if bash is missing */
163182
char *result = shell_prompt(prompt, echo);
164-
if (result || errno != ENOENT)
183+
if (result)
165184
return result;
166185

186+
if (echo && set_echo(1))
187+
return NULL;
167188
#endif
168189

169190
input_fh = fopen(INPUT_PATH, "r" FORCE_TEXT);

0 commit comments

Comments
 (0)