Skip to content

Commit

Permalink
Win32: implement stat() with symlink support
Browse files Browse the repository at this point in the history
With respect to symlinks, the current stat() implementation is almost the
same as lstat(): except for the file type (st_mode & S_IFMT), it returns
information about the link rather than the target.

Implement stat by opening the file with as little permissions as possible
and calling GetFileInformationByHandle on it. This way, all link resoltion
is handled by the Windows file system layer.

If symlinks are disabled, use 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>
  • Loading branch information
kblees authored and dscho committed Sep 24, 2024
1 parent b40940a commit e22994d
Showing 1 changed file with 18 additions and 1 deletion.
19 changes: 18 additions & 1 deletion compat/mingw.c
Original file line number Diff line number Diff line change
Expand Up @@ -974,9 +974,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_LONG_PATH];
HANDLE hnd;
int result;

/* open the file and let Windows resolve the links */
if (xutftowcs_long_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)
Expand Down

0 comments on commit e22994d

Please sign in to comment.