Skip to content

Commit 468a7e4

Browse files
ramsay-jonesttaylorr
authored andcommitted
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 7d5e9c9 (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 1f180e5 (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/[email protected]/ but I've tried to summarize the useful bits in this commit message. [jk: commit message] Signed-off-by: Jeff King <[email protected]> Signed-off-by: Ramsay Jones <[email protected]> Signed-off-by: Taylor Blau <[email protected]>
1 parent 34b6ce9 commit 468a7e4

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

builtin/credential-cache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ static int connection_fatally_broken(int error)
3030

3131
static int connection_closed(int error)
3232
{
33-
return (error == ECONNRESET);
33+
return error == ECONNRESET || error == ECONNABORTED;
3434
}
3535

3636
static int connection_fatally_broken(int error)

0 commit comments

Comments
 (0)