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.

If symlinks are disabled, use `mingw_lstat()` as before, but fail with
`ELOOP` if a symlink would have to be resolved.

Signed-off-by: Karsten Blees <blees@dcon.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Karsten Blees 2025-12-17 14:08:39 +00:00 committed by Junio C Hamano
parent e5be12952a
commit 25866d0c50

View File

@ -1026,9 +1026,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)