Re: [PATCH 02/18] mingw: implement `stat()` with symlink support
- From
Johannes Sixt <j6t@kdbg.org>
- Date
- Dec 18, 2025, 10:44 UTC
- Message-ID
- <46b69027-90b4-439a-a14d-61d1bb739b7b@kdbg.org>
- In-Reply-To
- <c36848eda76742f7a7c203868a077b790301344f.1765980535.git.gitgitgadget@gmail.com>
Am 17.12.25 um 15:08 schrieb Karsten Blees via GitGitGadget:
Show 12 quoted lines
> 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.
This last paragraph is disconnected from the patch text. I can't find a use of ELOOP anywhere in the code that has something to do with the goal of this patch. Is this a remnant from early times where symbolic links were optional?
The patch text looks good.
Show 39 quoted lines
>
> 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)-- Hannes