[PATCH 1/2] credential-cache--daemon: allow a concurrently created socket dir
- From
Farid Zakaria <farid.m.zakaria@gmail.com>
- Date
- Nov 1, 2026, 23:29 UTC
- Message-ID
- <20261101-fz-credential-cache-race-v1-1-28f0bac51e11@gmail.com>
- In-Reply-To
- <20261101-fz-credential-cache-race-v1-0-28f0bac51e11@gmail.com>
When no daemon is running, two "git credential-cache store" run at the same time each try to start one. If the socket directory does not exist yet, both daemons try to create it. The one that comes second dies:
fatal: unable to mkdir '<home>/.cache/git/credential': File exists
That client then fails with "cache daemon did not start".
The fix is to ignore EEXIST from mkdir(), and check the directory's permissions the same way as for one that already existed.
Signed-off-by: Farid Zakaria <farid.m.zakaria@gmail.com> --- builtin/credential-cache--daemon.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/builtin/credential-cache--daemon.c b/builtin/credential-cache--daemon.c index 65cc619bec..0dfa11e2ec 100644 --- a/builtin/credential-cache--daemon.c +++ b/builtin/credential-cache--daemon.c @@ -273,8 +273,18 @@ static void init_socket_directory(const char *path) */ if (safe_create_leading_directories_const(the_repository, dir) < 0) die_errno("unable to create directories for '%s'", dir); - if (mkdir(dir, 0700) < 0) - die_errno("unable to mkdir '%s'", dir); + if (mkdir(dir, 0700) < 0) { + if (errno != EEXIST) + die_errno("unable to mkdir '%s'", dir); + /* + * Another daemon created it first; check it like one + * that already existed. + */ + if (stat(dir, &st)) + die_errno("unable to stat '%s'", dir); + if (st.st_mode & 077) + die(_(permissions_advice), dir); + } } if (chdir(dir))
-- 2.55.0