Skip to content

Commit 1bd4e1e

Browse files
committed
Merge pull request #40 from nalla/git-terminal-prompt
mingw: Proper `git_terminal_prompt` with `xterm`
2 parents 22208dd + 50158a5 commit 1bd4e1e

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

compat/terminal.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
#include <inttypes.h>
12
#include "git-compat-util.h"
3+
#include "run-command.h"
24
#include "compat/terminal.h"
35
#include "sigchain.h"
46
#include "strbuf.h"
@@ -97,11 +99,62 @@ static int disable_echo(void)
9799
#define FORCE_TEXT
98100
#endif
99101

102+
static char *xterm_prompt(const char *prompt, int echo)
103+
{
104+
const char *env = getenv("MSYS_TTY_HANDLES");
105+
const char *echo_off[] = { "sh", "-c", "stty -echo </dev/tty", NULL };
106+
const char *echo_on[] = { "sh", "-c", "stty echo </dev/tty", NULL };
107+
static char buffer[1024];
108+
DWORD len, dummy;
109+
size_t tty0, tty1, tty2;
110+
HANDLE in_handle, out_handle;
111+
112+
if (!env || 3 != sscanf(env,
113+
" %" SCNuPTR " %" SCNuPTR " %" SCNuPTR " ",
114+
&tty0, &tty1, &tty2)) {
115+
warning("Cannot read from xterm");
116+
return NULL;
117+
}
118+
119+
in_handle = (HANDLE)tty0;
120+
out_handle = (HANDLE)tty1;
121+
122+
if (!echo && run_command_v_opt(echo_off, 0))
123+
warning("Could not disable echo on xterm");
124+
125+
if (!WriteFile(out_handle, prompt, strlen(prompt), &dummy, NULL)) {
126+
warning("Could not write to xterm");
127+
return NULL;
128+
}
129+
130+
if (!ReadFile(in_handle, buffer, 1024, &len, NULL)) {
131+
warning("Could not read from xterm");
132+
return NULL;
133+
}
134+
135+
if (len && buffer[len - 1] == '\n')
136+
buffer[--len] = '\0';
137+
if (len && buffer[len - 1] == '\r')
138+
buffer[--len] = '\0';
139+
140+
if (!echo) {
141+
if(run_command_v_opt(echo_on, 0))
142+
warning("Could not re-enable echo on xterm");
143+
WriteFile(out_handle, "\n", 1, &dummy, NULL);
144+
}
145+
146+
return len == 0 ? NULL : buffer;
147+
}
148+
100149
char *git_terminal_prompt(const char *prompt, int echo)
101150
{
102151
static struct strbuf buf = STRBUF_INIT;
103152
int r;
104153
FILE *input_fh, *output_fh;
154+
const char *term = getenv("TERM");
155+
156+
if (term && starts_with(term, "xterm"))
157+
return xterm_prompt(prompt, echo);
105158

106159
input_fh = fopen(INPUT_PATH, "r" FORCE_TEXT);
107160
if (!input_fh)

0 commit comments

Comments
 (0)