From 5437f0fd368c7faf1a0b5e1fef048232c1f2a3e6 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 1 Feb 2022 15:26:11 +0100 Subject: [PATCH] fixup! mingw: add a cache below mingw's lstat and dirent implementations Since df3458e95710 (refs API: make parse_loose_ref_contents() not set errno, 2021-10-16), `files_read_raw_ref()` assumes that `errno` is always set to a non-zero value upon failure. It even goes so far as to hard-code that assumption in a `BUG()` when that assumption is not met, rather than fail gracefully. According to https://pubs.opengroup.org/onlinepubs/9699919799/functions/lstat.html, `lstat()` shall indeed set `errno` upon failure, and https://pubs.opengroup.org/onlinepubs/9699919799/functions/errno.html indicates that indeed, the code may rely on `errno` being set to a non-zero value upon failure. In `fscache_lstat()`, we did not set `errno` upon a cache miss (which indicates that the item did not exist at the time the `lstat()` values were cached), and therefore we now trigger this problem all the time. Let's set `errno=ENOENT` when no entry was found. This fixes https://github.com/git-for-windows/git/issues/3674 Signed-off-by: Johannes Schindelin --- compat/win32/fscache.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compat/win32/fscache.c b/compat/win32/fscache.c index 174665608250e3..a0ddb33090058a 100644 --- a/compat/win32/fscache.c +++ b/compat/win32/fscache.c @@ -598,8 +598,10 @@ int fscache_lstat(const char *filename, struct stat *st) fsentry_init(&key[0].u.ent, NULL, filename, dirlen); fsentry_init(&key[1].u.ent, &key[0].u.ent, filename + base, len - base); fse = fscache_get(cache, &key[1].u.ent); - if (!fse) + if (!fse) { + errno = ENOENT; return -1; + } /* * Special case symbolic links: FindFirstFile()/FindNextFile() did not