Skip to content

Commit 8e8e2b7

Browse files
pks-tttaylorr
authored andcommitted
builtin/credential-cache--daemon: fix error when "exit"ing on Cygwin
Clients can signal the git-credential-cache(1) daemon that it is supposed to exit by sending it an "exit" command. The details around how exactly the daemon exits seem to be rather intricate as spelt out by a comment surrounding our call to exit(3p), as we need to be mindful around closing the client streams before we signal the client. The logic is broken on Cygwin though: when a client asks the daemon to exit, they won't see the EOF and will instead get an error message: fatal: read error from cache daemon: Software caused connection abort This issue is known in Cygwin, see for example [1], but the exact root cause is not known. As it turns out, we can avoid the issue by explicitly closing the client streams via fclose(3p). I'm not sure at all where the claimed atexit(3p) handler mentioned in the comment is supposed to live, but from all I can see we do not have any installed that would close the sockets for us. So this leaves me with a bit of a sour taste overall. That being said, I couldn't spot anything obviously wrong with closing the streams ourselves, and it does fix the issue on Cygwin without any regressions on other platforms as far as I can see. So let's go for this fix, even though I cannot properly explain it. [1]: cygporter/git#51 Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Taylor Blau <[email protected]>
1 parent 15030f9 commit 8e8e2b7

File tree

1 file changed

+4
-6
lines changed

1 file changed

+4
-6
lines changed

builtin/credential-cache--daemon.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,11 @@ static void serve_one_client(FILE *in, FILE *out)
156156
}
157157
else if (!strcmp(action.buf, "exit")) {
158158
/*
159-
* It's important that we clean up our socket first, and then
160-
* signal the client only once we have finished the cleanup.
161-
* Calling exit() directly does this, because we clean up in
162-
* our atexit() handler, and then signal the client when our
163-
* process actually ends, which closes the socket and gives
164-
* them EOF.
159+
* We must close our file handles before we exit such that the
160+
* client will receive an EOF.
165161
*/
162+
fclose(in);
163+
fclose(out);
166164
exit(0);
167165
}
168166
else if (!strcmp(action.buf, "erase"))

0 commit comments

Comments
 (0)