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>
This commit is contained in:
Karsten Blees
2015-05-24 01:17:31 +02:00
committed by Johannes Schindelin
parent 9bb137cc0b
commit 98dd951e26

View File

@@ -657,7 +657,24 @@ int mingw_chdir(const char *dirname)
wchar_t wdirname[MAX_LONG_PATH];
if (xutftowcs_long_path(wdirname, dirname) < 0)
return -1;
result = _wchdir(wdirname);
if (has_symlinks) {
HANDLE hnd = CreateFileW(wdirname, 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;
}
if (!GetFinalPathNameByHandleW(hnd, wdirname, ARRAY_SIZE(wdirname), 0)) {
errno = err_win_to_posix(GetLastError());
CloseHandle(hnd);
return -1;
}
CloseHandle(hnd);
}
result = _wchdir(normalize_ntpath(wdirname));
current_directory_len = GetCurrentDirectoryW(0, NULL);
return result;
}