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>

Karsten Blees committed Jan 9, 2026 at 20:04 UTC 48bc5094de4d2c549efd82780d4488071955d4ff
1 file changed +18 -1
compat/mingw.c
+18 -1
@@ -1027,9 +1027,26 @@ int mingw_lstat(const char *file_name, struct stat *buf)
1027 {
1028 return do_lstat(0, file_name, buf);
1029 }
1030 +
1031 int mingw_stat(const char *file_name, struct stat *buf)
1032 {
1032 - return do_lstat(1, file_name, buf);
1033 + wchar_t wfile_name[MAX_PATH];
1034 + HANDLE hnd;
1035 + int result;
1036 +
1037 + /* open the file and let Windows resolve the links */
1038 + if (xutftowcs_path(wfile_name, file_name) < 0)
1039 + return -1;
1040 + hnd = CreateFileW(wfile_name, 0,
1041 + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
1042 + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
1043 + if (hnd == INVALID_HANDLE_VALUE) {
1044 + errno = err_win_to_posix(GetLastError());
1045 + return -1;
1046 + }
1047 + result = get_file_info_by_handle(hnd, buf);
1048 + CloseHandle(hnd);
1049 + return result;
1050 }
1051
1052 int mingw_fstat(int fd, struct stat *buf)