/gist:6173cc1a84f747321a44 Secret
Created
February 7, 2012 09:43
Star
You must be signed in to star a gist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| commit 84d72733fc8cb90ac7fef04bb114da1e14d8b147 | |
| Author: Jeff King <peff@peff.net> | |
| Date: Fri Feb 3 17:16:02 2012 -0500 | |
| 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://peff@github.com': ': 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://peff@github.com': | |
| [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://peff@github.com': No such device or address | |
| Signed-off-by: Jeff King <peff@peff.net> | |
| Signed-off-by: Junio C Hamano <gitster@pobox.com> | |
| diff --git a/prompt.c b/prompt.c | |
| index 64f817b..d851807 100644 | |
| --- a/prompt.c | |
| +++ b/prompt.c | |
| @@ -7,29 +7,36 @@ | |
| static char *do_askpass(const char *cmd, const char *prompt) | |
| { | |
| struct child_process pass; | |
| const char *args[3]; | |
| static struct strbuf buffer = STRBUF_INIT; | |
| + int err = 0; | |
| args[0] = cmd; | |
| args[1] = prompt; | |
| args[2] = NULL; | |
| memset(&pass, 0, sizeof(pass)); | |
| pass.argv = args; | |
| pass.out = -1; | |
| if (start_command(&pass)) | |
| - exit(1); | |
| + return NULL; | |
| if (strbuf_read(&buffer, pass.out, 20) < 0) | |
| - die("failed to get '%s' from %s\n", prompt, cmd); | |
| + 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 strbuf_detach(&buffer, NULL); | |
| } | |
| commit 31b49d9b653803e7c7fd18b21c8bdd86e3421668 | |
| Author: Jeff King <peff@peff.net> | |
| Date: Fri Feb 3 17:14:11 2012 -0500 | |
| prompt: clean up strbuf usage | |
| The do_askpass function inherited a few bad habits from the | |
| original git_getpass. One, there's no need to strbuf_reset a | |
| buffer which was just initialized. And two, it's a good | |
| habit to use strbuf_detach to claim ownership of a buffer's | |
| string (even though in this case the owning buffer goes out | |
| of scope, so it's effectively the same thing). | |
| Signed-off-by: Jeff King <peff@peff.net> | |
| Signed-off-by: Junio C Hamano <gitster@pobox.com> | |
| diff --git a/prompt.c b/prompt.c | |
| index 72ab9de..64f817b 100644 | |
| --- a/prompt.c | |
| +++ b/prompt.c | |
| @@ -7,30 +7,29 @@ | |
| static char *do_askpass(const char *cmd, const char *prompt) | |
| { | |
| struct child_process pass; | |
| const char *args[3]; | |
| static struct strbuf buffer = STRBUF_INIT; | |
| args[0] = cmd; | |
| args[1] = prompt; | |
| args[2] = NULL; | |
| memset(&pass, 0, sizeof(pass)); | |
| pass.argv = args; | |
| pass.out = -1; | |
| if (start_command(&pass)) | |
| exit(1); | |
| - strbuf_reset(&buffer); | |
| if (strbuf_read(&buffer, pass.out, 20) < 0) | |
| die("failed to get '%s' from %s\n", prompt, cmd); | |
| close(pass.out); | |
| if (finish_command(&pass)) | |
| exit(1); | |
| strbuf_setlen(&buffer, strcspn(buffer.buf, "\r\n")); | |
| - return buffer.buf; | |
| + return strbuf_detach(&buffer, NULL); | |
| } | |
| commit 1cb0134f3414be187cc3eb98e9740aeeb07dcb16 | |
| Author: Jeff King <peff@peff.net> | |
| Date: Sat Dec 10 05:40:57 2011 -0500 | |
| refactor git_getpass into generic prompt function | |
| This will allow callers to specify more options (e.g., | |
| leaving echo on). The original git_getpass becomes a slim | |
| wrapper around the new function. | |
| Signed-off-by: Jeff King <peff@peff.net> | |
| Signed-off-by: Junio C Hamano <gitster@pobox.com> | |
| diff --git a/prompt.c b/prompt.c | |
| index 42a1c9f..2002644 100644 | |
| --- a/prompt.c | |
| +++ b/prompt.c | |
| @@ -6,43 +6,30 @@ | |
| -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; | |
| - 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; | |
| memset(&pass, 0, sizeof(pass)); | |
| pass.argv = args; | |
| pass.out = -1; | |
| if (start_command(&pass)) | |
| exit(1); | |
| strbuf_reset(&buffer); | |
| if (strbuf_read(&buffer, pass.out, 20) < 0) | |
| - die("failed to read password from %s\n", askpass); | |
| + die("failed to get '%s' from %s\n", prompt, cmd); | |
| close(pass.out); | |
| if (finish_command(&pass)) | |
| exit(1); | |
| strbuf_setlen(&buffer, strcspn(buffer.buf, "\r\n")); | |
| return buffer.buf; | |
| } | |
| commit d3c58b83aee2007ca76dc5d1242c09b6f7989c76 | |
| Author: Jeff King <peff@peff.net> | |
| Date: Sat Dec 10 05:40:54 2011 -0500 | |
| move git_getpass to its own source file | |
| This is currently in connect.c, but really has nothing to | |
| do with the git protocol itself. Let's make a new source | |
| file all about prompting the user, which will make it | |
| cleaner to refactor. | |
| Signed-off-by: Jeff King <peff@peff.net> | |
| Signed-off-by: Junio C Hamano <gitster@pobox.com> | |
| diff --git a/prompt.c b/prompt.c | |
| new file mode 100644 | |
| index 0000000..42a1c9f | |
| --- /dev/null | |
| +++ b/prompt.c | |
| @@ -0,0 +6,43 @@ | |
| +char *git_getpass(const char *prompt) | |
| +{ | |
| + const char *askpass; | |
| + struct child_process pass; | |
| + const char *args[3]; | |
| + static struct strbuf buffer = STRBUF_INIT; | |
| + | |
| + 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[1] = prompt; | |
| + args[2] = NULL; | |
| + | |
| + memset(&pass, 0, sizeof(pass)); | |
| + pass.argv = args; | |
| + pass.out = -1; | |
| + | |
| + if (start_command(&pass)) | |
| + exit(1); | |
| + | |
| + strbuf_reset(&buffer); | |
| + if (strbuf_read(&buffer, pass.out, 20) < 0) | |
| + die("failed to read password from %s\n", askpass); | |
| + | |
| + close(pass.out); | |
| + | |
| + if (finish_command(&pass)) | |
| + exit(1); | |
| + | |
| + strbuf_setlen(&buffer, strcspn(buffer.buf, "\r\n")); | |
| + | |
| + return buffer.buf; | |
| +} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment