Skip to content

Commit c34fe63

Browse files
peffgitster
authored andcommitted
disconnect from remote helpers more gently
When git spawns a remote helper program (like git-remote-http), the last thing we do before closing the pipe to the child process is to send a blank line, telling the helper that we are done issuing commands. However, the helper may already have exited, in which case the parent git process will receive SIGPIPE and die. In particular, this can happen with the remote-curl helper when it encounters errors during a push. The helper reports individual errors for each ref back to git-push, and then exits with a non-zero exit code. Depending on the exact timing of the write, the parent process may or may not receive SIGPIPE. This causes intermittent test failure in t5541.8, and is a side effect of 5238cbf (remote-curl: Fix push status report when all branches fail). Before that commit, remote-curl would not send the final blank line to indicate that the list of status lines was complete; it would just exit, closing the pipe. The parent git-push would notice the closed pipe while reading the status report and exit immediately itself, propagating the failing exit code. But post-5238cbf, remote-curl completes the status list before exiting, git-push actually runs to completion, and then it tries to cleanly disconnect the helper, leading to the SIGPIPE race above. This patch drops all error-checking when sending the final "we are about to hang up" blank line to helpers. There is nothing useful for the parent process to do about errors at that point anyway, and certainly failing to send our "we are done with commands" line to a helper that has already exited is not a problem. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5238cbf commit c34fe63

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

transport-helper.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "remote.h"
1010
#include "string-list.h"
1111
#include "thread-utils.h"
12+
#include "sigchain.h"
1213

1314
static int debug;
1415

@@ -203,14 +204,20 @@ static struct child_process *get_helper(struct transport *transport)
203204
static int disconnect_helper(struct transport *transport)
204205
{
205206
struct helper_data *data = transport->data;
206-
struct strbuf buf = STRBUF_INIT;
207207

208208
if (data->helper) {
209209
if (debug)
210210
fprintf(stderr, "Debug: Disconnecting.\n");
211211
if (!data->no_disconnect_req) {
212-
strbuf_addf(&buf, "\n");
213-
sendline(data, &buf);
212+
/*
213+
* Ignore write errors; there's nothing we can do,
214+
* since we're about to close the pipe anyway. And the
215+
* most likely error is EPIPE due to the helper dying
216+
* to report an error itself.
217+
*/
218+
sigchain_push(SIGPIPE, SIG_IGN);
219+
xwrite(data->helper->in, "\n", 1);
220+
sigchain_pop(SIGPIPE);
214221
}
215222
close(data->helper->in);
216223
close(data->helper->out);

0 commit comments

Comments
 (0)