#include "run-command.h"
#include "strbuf.h"
#include "prompt.h"
+#include "compat/terminal.h"
-char *git_getpass(const char *prompt)
+static char *do_askpass(const char *cmd, const char *prompt)
{
- const char *askpass;
struct child_process pass;
const char *args[3];
static struct strbuf buffer = STRBUF_INIT;
+ int err = 0;
- askpass = getenv("GIT_ASKPASS");
- if (!askpass)
- askpass = askpass_program;
- if (!askpass)
- askpass = getenv("SSH_ASKPASS");
- if (!askpass || !(*askpass)) {
- char *result = getpass(prompt);
- if (!result)
- die_errno("Could not read password");
- return result;
- }
-
- args[0] = askpass;
+ args[0] = cmd;
args[1] = prompt;
args[2] = NULL;
pass.out = -1;
if (start_command(&pass))
- exit(1);
+ return NULL;
- strbuf_reset(&buffer);
if (strbuf_read(&buffer, pass.out, 20) < 0)
- die("failed to read password from %s\n", askpass);
+ err = 1;
close(pass.out);
if (finish_command(&pass))
- exit(1);
+ err = 1;
+
+ if (err) {
+ error("unable to read askpass response from '%s'", cmd);
+ strbuf_release(&buffer);
+ return NULL;
+ }
strbuf_setlen(&buffer, strcspn(buffer.buf, "\r\n"));
- return buffer.buf;
+ return strbuf_detach(&buffer, NULL);
+}
+
+char *git_prompt(const char *prompt, int flags)
+{
+ char *r = NULL;
+
+ if (flags & PROMPT_ASKPASS) {
+ const char *askpass;
+
+ askpass = getenv("GIT_ASKPASS");
+ if (!askpass)
+ askpass = askpass_program;
+ if (!askpass)
+ askpass = getenv("SSH_ASKPASS");
+ if (askpass && *askpass)
+ r = do_askpass(askpass, prompt);
+ }
+
+ if (!r)
+ r = git_terminal_prompt(prompt, flags & PROMPT_ECHO);
+ if (!r) {
+ /* prompts already contain ": " at the end */
+ die("could not read %s%s", prompt, strerror(errno));
+ }
+ return r;
+}
+
+char *git_getpass(const char *prompt)
+{
+ return git_prompt(prompt, PROMPT_ASKPASS);
}