Skip to content

Commit 84d7273

Browse files
peffgitster
authored andcommitted
prompt: fall back to terminal if askpass fails
The current askpass code simply dies if calling an askpass helper fails. Worse, in some failure modes it doesn't even print an error (if start_command fails, then it prints its own error; if reading fails, we print an error; but if the command exits non-zero, finish_command fails and we print nothing!). Let's be more kind to the user by printing an error message when askpass doesn't work out, and then falling back to the terminal (which also may fail, of course, but we die already there with a nice message). While we're at it, let's clean up the existing error messages a bit. Now that our prompts are very long and contain quotes and colons themselves, our error messages are hard to read. So the new failure modes look like: [before, with a terminal] $ GIT_ASKPASS=false git push $ echo $? 128 [before, with no terminal, and we must give up] $ setsid git push fatal: could not read 'Password for 'https://[email protected]': ': No such device or address [after, with a terminal] $ GIT_ASKPASS=false git push error: unable to read askpass response from 'false' Password for 'https://[email protected]': [after, with no terminal, and we must give up] $ GIT_ASKPASS=false setsid git push error: unable to read askpass response from 'false' fatal: could not read Password for 'https://[email protected]': No such device or address Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 31b49d9 commit 84d7273

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

prompt.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ static char *do_askpass(const char *cmd, const char *prompt)
99
struct child_process pass;
1010
const char *args[3];
1111
static struct strbuf buffer = STRBUF_INIT;
12+
int err = 0;
1213

1314
args[0] = cmd;
1415
args[1] = prompt;
@@ -19,15 +20,21 @@ static char *do_askpass(const char *cmd, const char *prompt)
1920
pass.out = -1;
2021

2122
if (start_command(&pass))
22-
exit(1);
23+
return NULL;
2324

2425
if (strbuf_read(&buffer, pass.out, 20) < 0)
25-
die("failed to get '%s' from %s\n", prompt, cmd);
26+
err = 1;
2627

2728
close(pass.out);
2829

2930
if (finish_command(&pass))
30-
exit(1);
31+
err = 1;
32+
33+
if (err) {
34+
error("unable to read askpass response from '%s'", cmd);
35+
strbuf_release(&buffer);
36+
return NULL;
37+
}
3138

3239
strbuf_setlen(&buffer, strcspn(buffer.buf, "\r\n"));
3340

@@ -36,7 +43,7 @@ static char *do_askpass(const char *cmd, const char *prompt)
3643

3744
char *git_prompt(const char *prompt, int flags)
3845
{
39-
char *r;
46+
char *r = NULL;
4047

4148
if (flags & PROMPT_ASKPASS) {
4249
const char *askpass;
@@ -47,12 +54,15 @@ char *git_prompt(const char *prompt, int flags)
4754
if (!askpass)
4855
askpass = getenv("SSH_ASKPASS");
4956
if (askpass && *askpass)
50-
return do_askpass(askpass, prompt);
57+
r = do_askpass(askpass, prompt);
5158
}
5259

53-
r = git_terminal_prompt(prompt, flags & PROMPT_ECHO);
5460
if (!r)
55-
die_errno("could not read '%s'", prompt);
61+
r = git_terminal_prompt(prompt, flags & PROMPT_ECHO);
62+
if (!r) {
63+
/* prompts already contain ": " at the end */
64+
die("could not read %s%s", prompt, strerror(errno));
65+
}
5666
return r;
5767
}
5868

0 commit comments

Comments
 (0)