When using gpg with some console based gpg-agent, acquiring the passphrase through the agent fails if stdin and stdout of gpg are redirected. With this commit, git-tag uses temporary files instead of standard input/output when signing a tag to support such gpg-agent usage. The problem was reported by Loïc Minier through http://bugs.debian.org/507642 Signed-off-by: Gerrit Pape <pape@xxxxxxxxxxx> --- builtin-tag.c | 51 ++++++++++++++++++++++++++++++++++----------------- 1 files changed, 34 insertions(+), 17 deletions(-) diff --git a/builtin-tag.c b/builtin-tag.c index 01e7374..e350352 100644 --- a/builtin-tag.c +++ b/builtin-tag.c @@ -159,10 +159,15 @@ static int verify_tag(const char *name, const char *ref, static int do_sign(struct strbuf *buffer) { struct child_process gpg; - const char *args[4]; + const char *args[7]; char *bracket; int len; int i, j; + int fd; + char *unsignpath, *signpath; + + unsignpath = git_pathdup("TAG_UNSIGNEDMSG"); + signpath = git_pathdup("TAG_SIGNEDMSG"); if (!*signingkey) { if (strlcpy(signingkey, git_committer_info(IDENT_ERROR_ON_NO_NAME), @@ -179,27 +184,39 @@ static int do_sign(struct strbuf *buffer) memset(&gpg, 0, sizeof(gpg)); gpg.argv = args; - gpg.in = -1; - gpg.out = -1; + gpg.in = 0; + gpg.out = 1; args[0] = "gpg"; args[1] = "-bsau"; args[2] = signingkey; - args[3] = NULL; - - if (start_command(&gpg)) - return error("could not run gpg."); - - if (write_in_full(gpg.in, buffer->buf, buffer->len) != buffer->len) { - close(gpg.in); - close(gpg.out); - finish_command(&gpg); - return error("gpg did not accept the tag data"); + args[3] = "-o"; + args[4] = signpath; + args[5] = unsignpath; + args[6] = NULL; + + fd = open(unsignpath, O_CREAT | O_TRUNC | O_WRONLY, 0600); + if (fd < 0) + die("could not create file '%s': %s", + unsignpath, strerror(errno)); + write_or_die(fd, buffer->buf, buffer->len); + close(fd); + + if (run_command(&gpg)) { + unlink(unsignpath); + unlink(signpath); + return error("gpg failed."); } - close(gpg.in); - len = strbuf_read(buffer, gpg.out, 1024); - close(gpg.out); + unlink(unsignpath); + + fd = open(signpath, O_RDONLY); + if (fd < 0) + die ("could not open file '%s': %s", + signpath, strerror(errno)); + len = strbuf_read(buffer, fd, 1024); + close(fd); + unlink(signpath); - if (finish_command(&gpg) || !len || len < 0) + if (!len || len < 0) return error("gpg failed to sign the tag"); /* Strip CR from the line endings, in case we are on Windows. */ -- 1.6.1.3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html