git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] remote-curl: Fix push status report when all branches fail

From
Jeff King <peff@peff.net>
Date
Feb 23, 2012, 10:04 UTC
Message-ID
<20120223100434.GA3083@sigill.intra.peff.net>
In-Reply-To
<20120222204050.GB6781@sigill.intra.peff.net>
On Wed, Feb 22, 2012 at 03:40:50PM -0500, Jeff King wrote:
> I'll re-send the patch with a stand-alone commit message.
Here it is.
-- >8 --
Subject: [PATCH] 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 <peff@peff.net>
---
 transport-helper.c |   13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/transport-helper.c b/transport-helper.c
index 6f227e2..f6b3b1f 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -9,6 +9,7 @@
 #include "remote.h"
 #include "string-list.h"
 #include "thread-utils.h"
+#include "sigchain.h"
 
 static int debug;
 
@@ -220,15 +221,21 @@ static struct child_process *get_helper(struct transport *transport)
 static int disconnect_helper(struct transport *transport)
 {
 	struct helper_data *data = transport->data;
-	struct strbuf buf = STRBUF_INIT;
 	int res = 0;
 
 	if (data->helper) {
 		if (debug)
 			fprintf(stderr, "Debug: Disconnecting.\n");
 		if (!data->no_disconnect_req) {
-			strbuf_addf(&buf, "\n");
-			sendline(data, &buf);
+			/*
+			 * Ignore write errors; there's nothing we can do,
+			 * since we're about to close the pipe anyway. And the
+			 * most likely error is EPIPE due to the helper dying
+			 * to report an error itself.
+			 */
+			sigchain_push(SIGPIPE, SIG_IGN);
+			xwrite(data->helper->in, "\n", 1);
+			sigchain_pop(SIGPIPE);
 		}
 		close(data->helper->in);
 		close(data->helper->out);
-- 
1.7.8.4.8.g10fac
Previous: Jeff KingNext: Junio C Hamano
Message 13 of 14 in “remote-curl: Fix push status report when all branches fail”
  1. remote-curl: Fix push status report when all branches failShawn O. Pearce, Jan 19, 2012
  2. Junio C HamanoJan 19, 2012
  3. remote-curl: Fix push status report when all branches failShawn O. Pearce, Jan 20, 2012
  4. Junio C HamanoJan 20, 2012
  5. Junio C HamanoJan 20, 2012
  6. Shawn PearceJan 20, 2012
  7. Thomas RastJan 20, 2012
  8. remote-curl: Fix push status report when all branches failShawn O. Pearce, Jan 20, 2012
  9. Junio C HamanoJan 20, 2012
  10. Jeff KingFeb 22, 2012
  11. Shawn PearceFeb 22, 2012
  12. Jeff KingFeb 22, 2012
  13. Jeff KingFeb 23, 2012
  14. Junio C HamanoFeb 23, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.