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

[PATCH] credential-cache: treat ECONNABORTED like ECONNRESET

From
Jeff King <peff@peff.net>
Date
Oct 18, 2024, 05:29 UTC
Message-ID
<20241018052952.GE2408674@coredump.intra.peff.net>
In-Reply-To
<658fe4fa540a0a5316e11ed43f9139d5ef818ee5.1729226155.git.ps@pks.im>
On Fri, Oct 18, 2024 at 06:36:11AM +0200, Patrick Steinhardt wrote:
> Subject: builtin/credential-cache--daemon: fix error when "exit"ing on Cygwin

I think this commit message has a few unclear or inaccurate bits, because it's based on the earlier attempt. E.g., the change is now on the client side, not in credential-cache--daemon.

And I think rather than say "the daemon exit rules are intricate", we can actually outline the rules. :)

So here's what I had written after reading through the old thread. It would preferably get Ramsay's Signed-off-by before being applied.

-- >8 --
From: Ramsay Jones <ramsay@ramsayjones.plus.com>
Subject: [PATCH] credential-cache: treat ECONNABORTED like ECONNRESET

On Cygwin, t0301 fails because "git credential-cache exit" returns a non-zero exit code. What's supposed to happen here is:

  1. The client (the "credential-cache" invocation above) connects to a
     previously-spawned credential-cache--daemon.
  2. The client sends an "exit" command to the daemon.
  3. The daemon unlinks the socket and then exits, closing the
     descriptor back to the client.
  4. The client sees EOF on the descriptor and exits successfully.

That works on most platforms, and even _used_ to work on Cygwin. But that changed in Cygwin's ef95c03522 (Cygwin: select: Fix FD_CLOSE handling, 2021-04-06). After that commit, the client sees a read error with errno set to ECONNABORTED, and it reports the error and dies.

It's not entirely clear if this is a Cygwin bug. It seems that calling fclose() on the filehandles pointing to the sockets is sufficient to avoid this error return, even though exiting should in general look the same from the client's perspective.

However, we can't just call fclose() here. It's important in step 3 above to unlink the socket before closing the descriptor to avoid the race mentioned by 7d5e9c9849 (credential-cache--daemon: clarify "exit" action semantics, 2016-03-18). The client will exit as soon as it sees the descriptor close, and the daemon may or may not have actually unlinked the socket by then. That makes test code like this:

  git credential exit &&
  test_path_is_missing .git-credential-cache
racy.
So we probably _could_ fix this by calling:
  delete_tempfile(&socket_file);
  fclose(in);
  fclose(out);

before we exit(). Or by replacing the exit() with a return up the stack, in which case the fclose() happens as we unwind. But in that case we'd still need to call delete_tempfile() here to avoid the race.

But simpler still is that we can notice that we already special-case ECONNRESET on the client side, courtesy of 1f180e5eb9 (credential-cache: interpret an ECONNRESET as an EOF, 2017-07-27). We can just do the same thing here (I suspect that prior to the Cygwin commit that introduced this problem, we were really just seeing ECONNRESET instead of ECONNABORTED, so the "new" problem is just the switch of the errno values).

There's loads more debugging in this thread:
  https://lore.kernel.org/git/9dc3e85f-a532-6cff-de11-1dfb2e4bc6b6@ramsayjones.plus.com/
but I've tried to summarize the useful bits in this commit message.
[jk: commit message]
Signed-off-by: Jeff King <peff@peff.net>
---
 builtin/credential-cache.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/builtin/credential-cache.c b/builtin/credential-cache.c
index 5de8b9123b..7789d57d3e 100644
--- a/builtin/credential-cache.c
+++ b/builtin/credential-cache.c
@@ -30,7 +30,7 @@ static int connection_fatally_broken(int error)
 
 static int connection_closed(int error)
 {
-	return (error == ECONNRESET);
+	return error == ECONNRESET || error == ECONNABORTED;
 }
 
 static int connection_fatally_broken(int error)
-- 
2.47.0.273.g4ed1498264
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 13 of 22 in “builtin/credential-cache--daemon: fix error when "exit"ing on Cygwin”
  1. builtin/credential-cache--daemon: fix error when "exit"ing on CygwinPatrick Steinhardt, Oct 16, 2024
  2. Jeff KingOct 16, 2024
  3. Jeff KingOct 16, 2024
  4. Ramsay JonesOct 16, 2024
  5. Taylor BlauOct 16, 2024
  6. Jeff KingOct 17, 2024
  7. Patrick SteinhardtOct 17, 2024
  8. Ramsay JonesOct 17, 2024
  9. Patrick SteinhardtOct 18, 2024
  10. Taylor BlauOct 17, 2024
  11. Ramsay JonesOct 16, 2024
  12. builtin/credential-cache--daemon: fix error when "exit"ing on CygwinPatrick Steinhardt, Oct 18, 2024
  13. credential-cache: treat ECONNABORTED like ECONNRESETJeff King, Oct 18, 2024
  14. Patrick SteinhardtOct 18, 2024
  15. Ramsay JonesOct 18, 2024
  16. Taylor BlauOct 18, 2024
  17. Kristoffer HaugsbakkOct 18, 2024
  18. Jeff KingOct 19, 2024
  19. Comment trailers vs. bracketed linesKristoffer Haugsbakk, Oct 20, 2024
  20. Kristoffer HaugsbakkMay 7, 2025
  21. Jeff KingMay 8, 2025
  22. Junio C HamanoMay 7, 2025

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.