Skip to content

Commit 12e7db5

Browse files
kbleesdscho
authored andcommitted
Win32: mingw_chdir: change to symlink-resolved directory
If symlinks are enabled, resolve all symlinks when changing directories, as required by POSIX. Note: Git's real_path() function bases its link resolution algorithm on this property of chdir(). Unfortunately, the current directory on Windows is limited to only MAX_PATH (260) characters. Therefore using symlinks and long paths in combination may be problematic. Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent a831f01 commit 12e7db5

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

compat/mingw.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,24 @@ int mingw_chdir(const char *dirname)
899899
wchar_t wdirname[MAX_LONG_PATH];
900900
if (xutftowcs_long_path(wdirname, dirname) < 0)
901901
return -1;
902-
result = _wchdir(wdirname);
902+
903+
if (has_symlinks) {
904+
HANDLE hnd = CreateFileW(wdirname, 0,
905+
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
906+
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
907+
if (hnd == INVALID_HANDLE_VALUE) {
908+
errno = err_win_to_posix(GetLastError());
909+
return -1;
910+
}
911+
if (!GetFinalPathNameByHandleW(hnd, wdirname, ARRAY_SIZE(wdirname), 0)) {
912+
errno = err_win_to_posix(GetLastError());
913+
CloseHandle(hnd);
914+
return -1;
915+
}
916+
CloseHandle(hnd);
917+
}
918+
919+
result = _wchdir(normalize_ntpath(wdirname));
903920
current_directory_len = GetCurrentDirectoryW(0, NULL);
904921
return result;
905922
}

0 commit comments

Comments
 (0)