|
4 | 4 | #include "compat/terminal.h"
|
5 | 5 | #include "sigchain.h"
|
6 | 6 | #include "strbuf.h"
|
| 7 | +#include "cache.h" |
7 | 8 |
|
8 | 9 | #if defined(HAVE_DEV_TTY) || defined(GIT_WINDOWS_NATIVE)
|
9 | 10 |
|
@@ -95,49 +96,63 @@ static int disable_echo(void)
|
95 | 96 |
|
96 | 97 | static char *xterm_prompt(const char *prompt, int echo)
|
97 | 98 | {
|
98 |
| - const char *env = getenv("MSYS_TTY_HANDLES"); |
| 99 | + const char *read_password[] = { |
| 100 | + "sh", "-c", |
| 101 | + "cat >/dev/tty && read line </dev/tty && echo \"$line\"", |
| 102 | + NULL |
| 103 | + }; |
99 | 104 | const char *echo_off[] = { "sh", "-c", "stty -echo </dev/tty", NULL };
|
100 | 105 | const char *echo_on[] = { "sh", "-c", "stty echo </dev/tty", NULL };
|
101 |
| - static char buffer[1024]; |
102 |
| - DWORD len, dummy; |
103 |
| - size_t tty0, tty1, tty2; |
104 |
| - HANDLE in_handle, out_handle; |
105 |
| - |
106 |
| - if (!env || 3 != sscanf(env, |
107 |
| - " %" SCNuPTR " %" SCNuPTR " %" SCNuPTR " ", |
108 |
| - &tty0, &tty1, &tty2)) { |
109 |
| - warning("Cannot read from xterm"); |
110 |
| - return NULL; |
111 |
| - } |
112 |
| - |
113 |
| - in_handle = (HANDLE)tty0; |
114 |
| - out_handle = (HANDLE)tty1; |
| 106 | + const char *new_line[] = { "sh", "-c", "printf '\\n' >/dev/tty", NULL }; |
| 107 | + struct child_process child = CHILD_PROCESS_INIT; |
| 108 | + static struct strbuf buffer = STRBUF_INIT; |
| 109 | + int prompt_len = strlen(prompt), len = -1, code; |
115 | 110 |
|
116 | 111 | if (!echo && run_command_v_opt(echo_off, 0))
|
117 | 112 | warning("Could not disable echo on xterm");
|
118 | 113 |
|
119 |
| - if (!WriteFile(out_handle, prompt, strlen(prompt), &dummy, NULL)) { |
120 |
| - warning("Could not write to xterm"); |
121 |
| - return NULL; |
| 114 | + child.argv = read_password; |
| 115 | + child.in = -1; |
| 116 | + child.out = -1; |
| 117 | + |
| 118 | + code = start_command(&child); |
| 119 | + if (code) { |
| 120 | + error("Could not access xterm"); |
| 121 | + goto ret; |
122 | 122 | }
|
123 | 123 |
|
124 |
| - if (!ReadFile(in_handle, buffer, 1024, &len, NULL)) { |
125 |
| - warning("Could not read from xterm"); |
126 |
| - return NULL; |
| 124 | + if (write_in_full(child.in, prompt, prompt_len) != prompt_len) { |
| 125 | + error("Could not write to xterm"); |
| 126 | + close(child.in); |
| 127 | + close(child.out); |
| 128 | + goto ret; |
127 | 129 | }
|
| 130 | + close(child.in); |
| 131 | + |
| 132 | + strbuf_setlen(&buffer, 0); |
| 133 | + len = strbuf_read(&buffer, child.out, 1024); |
| 134 | + close(child.out); |
| 135 | + if (len < 0) { |
| 136 | + error("Could not read from xterm"); |
| 137 | + goto ret; |
| 138 | + } |
| 139 | + |
| 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); |
128 | 144 |
|
129 |
| - if (len && buffer[len - 1] == '\n') |
130 |
| - buffer[--len] = '\0'; |
131 |
| - if (len && buffer[len - 1] == '\r') |
132 |
| - buffer[--len] = '\0'; |
| 145 | +ret: |
| 146 | + if (!code) |
| 147 | + finish_command(&child); |
133 | 148 |
|
134 | 149 | if (!echo) {
|
135 |
| - if(run_command_v_opt(echo_on, 0)) |
136 |
| - warning("Could not re-enable echo on xterm"); |
137 |
| - WriteFile(out_handle, "\n", 1, &dummy, NULL); |
| 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); |
138 | 153 | }
|
139 | 154 |
|
140 |
| - return len == 0 ? NULL : buffer; |
| 155 | + return len < 0 ? NULL : buffer.buf; |
141 | 156 | }
|
142 | 157 |
|
143 | 158 | #endif
|
|
0 commit comments