[PATCH 02/18] mingw: implement `stat()` with symlink support
- From
Karsten Blees via GitGitGadget <gitgitgadget@gmail.com>
- Date
- Dec 17, 2025, 14:08 UTC
- Message-ID
- <c36848eda76742f7a7c203868a077b790301344f.1765980535.git.gitgitgadget@gmail.com>
- In-Reply-To
- <pull.2018.git.1765980535.gitgitgadget@gmail.com>
From: Karsten Blees <blees@dcon.de>
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> --- compat/mingw.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/compat/mingw.c b/compat/mingw.c index f5a0fe3325..59afd69686 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -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)
-- gitgitgadget