sign_buffer: use pipe_command

Similar to the prior commit for verify_signed_buffer, the motivation here is both to make the code simpler, and to avoid any possible deadlocks with gpg. In this case we have the same "write to stdin, then read from stdout" that the verify case had. This is unlikely to be a problem in practice, since stdout has the detached signature, which it cannot compute until it has read all of stdin (if it were a non-detached signature, that would be a problem, though). We don't read from stderr at all currently. However, we will want to in a future patch, so this also prepares us there (and in that case gpg _does_ write before reading all of the input, though again, it is unlikely that a key uid will fill up a pipe buffer). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Jun 17, 2016 at 19:38 UTC 0581b546419627d4e82f7df8b195fa207ef42f6a
1 file changed +5 -19
gpg-interface.c
+5 -19
@@ -151,40 +151,26 @@ const char *get_signing_key(void)
151 int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key)
152 {
153 struct child_process gpg = CHILD_PROCESS_INIT;
154 - ssize_t len;
154 + int ret;
155 size_t i, j, bottom;
156
157 - gpg.in = -1;
158 - gpg.out = -1;
157 argv_array_pushl(&gpg.args,
158 gpg_program,
159 "-bsau", signing_key,
160 NULL);
161
164 - if (start_command(&gpg))
165 - return error(_("could not run gpg."));
162 + bottom = signature->len;
163
164 /*
165 * When the username signingkey is bad, program could be terminated
166 * because gpg exits without reading and then write gets SIGPIPE.
167 */
168 sigchain_push(SIGPIPE, SIG_IGN);
172 -
173 - if (write_in_full(gpg.in, buffer->buf, buffer->len) != buffer->len) {
174 - close(gpg.in);
175 - close(gpg.out);
176 - finish_command(&gpg);
177 - return error(_("gpg did not accept the data"));
178 - }
179 - close(gpg.in);
180 -
181 - bottom = signature->len;
182 - len = strbuf_read(signature, gpg.out, 1024);
183 - close(gpg.out);
184 -
169 + ret = pipe_command(&gpg, buffer->buf, buffer->len,
170 + signature, 1024, NULL, 0);
171 sigchain_pop(SIGPIPE);
172
187 - if (finish_command(&gpg) || !len || len < 0)
173 + if (ret || signature->len == bottom)
174 return error(_("gpg failed to sign the data"));
175
176 /* Strip CR from the line endings, in case we are on Windows. */