aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarsten Blees <karsten.blees@gmail.com>2026-01-09 20:04:59 +0000
committerJunio C Hamano <gitster@pobox.com>2026-01-09 18:32:54 -0800
commit48bc5094de4d2c549efd82780d4488071955d4ff (patch)
tree88375c0d7e186c025b29d490e47657dc738af2e9
parentmingw: don't call `GetFileAttributes()` twice in `mingw_lstat()` (diff)
downloadgit-48bc5094de4d2c549efd82780d4488071955d4ff.tar.gz
git-48bc5094de4d2c549efd82780d4488071955d4ff.zip
mingw: implement `stat()` with symlink support
With respect to symlinks, the current `mingw_stat()` implementation is almost identical to `mingw_lstat()`: except for the file type (`st_mode & S_IFMT`), it returns information about the link rather than the target. Implement `mingw_stat()` by opening the file handle requesting minimal permissions, and then calling `GetFileInformationByHandle()` on it. This way, all links are resolved by the Windows file system layer. Signed-off-by: Karsten Blees <karsten.blees@gmail.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--compat/mingw.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/compat/mingw.c b/compat/mingw.c
index ae6826948e..13970ae729 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -1027,9 +1027,26 @@ int mingw_lstat(const char *file_name, struct stat *buf)
{
return do_lstat(0, file_name, buf);
}
+
int mingw_stat(const char *file_name, struct stat *buf)
{
- return do_lstat(1, file_name, buf);
+ wchar_t wfile_name[MAX_PATH];
+ HANDLE hnd;
+ int result;
+
+ /* open the file and let Windows resolve the links */
+ if (xutftowcs_path(wfile_name, file_name) < 0)
+ return -1;
+ hnd = CreateFileW(wfile_name, 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (hnd == INVALID_HANDLE_VALUE) {
+ errno = err_win_to_posix(GetLastError());
+ return -1;
+ }
+ result = get_file_info_by_handle(hnd, buf);
+ CloseHandle(hnd);
+ return result;
}
int mingw_fstat(int fd, struct stat *buf)