Skip to content

Commit 243924a

Browse files
committed
Merge pull request #141 from kblees/kb/terminal-prompt
git_terminal_prompt fixes and Unicode support
2 parents 975e780 + 761f1f5 commit 243924a

File tree

1 file changed

+24
-33
lines changed

1 file changed

+24
-33
lines changed

compat/terminal.c

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -94,62 +94,50 @@ static int disable_echo(void)
9494
return 0;
9595
}
9696

97-
static char *xterm_prompt(const char *prompt, int echo)
97+
static char *shell_prompt(const char *prompt, int echo)
9898
{
9999
const char *read_input[] = {
100-
"sh", "-c",
101-
"cat >/dev/tty && read line </dev/tty && echo \"$line\"",
100+
/* Note: call 'bash' explicitly, as 'read -s' is bash-specific */
101+
"bash", "-c", echo ?
102+
"cat >/dev/tty && read -r line </dev/tty && echo \"$line\"" :
103+
"cat >/dev/tty && read -r -s line </dev/tty && echo \"$line\" && echo >/dev/tty",
102104
NULL
103105
};
104-
const char *echo_off[] = { "sh", "-c", "stty -echo </dev/tty", NULL };
105-
const char *echo_on[] = { "sh", "-c", "stty echo </dev/tty", NULL };
106-
const char *new_line[] = { "sh", "-c", "printf '\\n' >/dev/tty", NULL };
107106
struct child_process child = CHILD_PROCESS_INIT;
108107
static struct strbuf buffer = STRBUF_INIT;
109108
int prompt_len = strlen(prompt), len = -1, code;
110109

111-
if (!echo && run_command_v_opt(echo_off, 0))
112-
warning("Could not disable echo on xterm");
113-
114110
child.argv = read_input;
115111
child.in = -1;
116112
child.out = -1;
113+
child.silent_exec_failure = 1;
117114

118-
code = start_command(&child);
119-
if (code) {
120-
error("Could not access xterm");
121-
goto ret;
122-
}
115+
if (start_command(&child))
116+
return NULL;
123117

124118
if (write_in_full(child.in, prompt, prompt_len) != prompt_len) {
125-
error("Could not write to xterm");
119+
error("could not write to prompt script");
126120
close(child.in);
127-
close(child.out);
128121
goto ret;
129122
}
130123
close(child.in);
131124

132-
strbuf_setlen(&buffer, 0);
125+
strbuf_reset(&buffer);
133126
len = strbuf_read(&buffer, child.out, 1024);
134-
close(child.out);
135127
if (len < 0) {
136-
error("Could not read from xterm");
128+
error("could not read from prompt script");
137129
goto ret;
138130
}
139131

140-
if (len && buffer.buf[len - 1] == '\n')
141-
strbuf_setlen(&buffer, len - 1);
142-
if (len && buffer.buf[len - 1] == '\r')
143-
strbuf_setlen(&buffer, len - 1);
132+
strbuf_strip_suffix(&buffer, "\n");
133+
strbuf_strip_suffix(&buffer, "\r");
144134

145135
ret:
146-
if (!code)
147-
finish_command(&child);
148-
149-
if (!echo) {
150-
if (run_command_v_opt(echo_on, 0))
151-
warning("Could not enable echo on xterm");
152-
run_command_v_opt(new_line, 0);
136+
close(child.out);
137+
code = finish_command(&child);
138+
if (code) {
139+
error("failed to execute prompt script (exit code %d)", code);
140+
return NULL;
153141
}
154142

155143
return len < 0 ? NULL : buffer.buf;
@@ -166,11 +154,14 @@ char *git_terminal_prompt(const char *prompt, int echo)
166154
static struct strbuf buf = STRBUF_INIT;
167155
int r;
168156
FILE *input_fh, *output_fh;
157+
169158
#ifdef GIT_WINDOWS_NATIVE
170-
const char *term = getenv("TERM");
171159

172-
if (term && starts_with(term, "xterm"))
173-
return xterm_prompt(prompt, echo);
160+
/* try shell_prompt first, fall back to CONIN/OUT if bash is missing */
161+
char *result = shell_prompt(prompt, echo);
162+
if (result || errno != ENOENT)
163+
return result;
164+
174165
#endif
175166

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

0 commit comments

Comments
 (0)