Skip to content

Commit f79cf31

Browse files
kbleesdscho
authored andcommitted
mingw: allow mingw_chdir() to change to symlink-resolved directories
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 <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 3670a0a commit f79cf31

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

compat/mingw.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -866,9 +866,27 @@ int mingw_access(const char *filename, int mode)
866866
int mingw_chdir(const char *dirname)
867867
{
868868
wchar_t wdirname[MAX_PATH];
869+
869870
if (xutftowcs_path(wdirname, dirname) < 0)
870871
return -1;
871-
return _wchdir(wdirname);
872+
873+
if (has_symlinks) {
874+
HANDLE hnd = CreateFileW(wdirname, 0,
875+
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
876+
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
877+
if (hnd == INVALID_HANDLE_VALUE) {
878+
errno = err_win_to_posix(GetLastError());
879+
return -1;
880+
}
881+
if (!GetFinalPathNameByHandleW(hnd, wdirname, ARRAY_SIZE(wdirname), 0)) {
882+
errno = err_win_to_posix(GetLastError());
883+
CloseHandle(hnd);
884+
return -1;
885+
}
886+
CloseHandle(hnd);
887+
}
888+
889+
return _wchdir(normalize_ntpath(wdirname));
872890
}
873891

874892
int mingw_chmod(const char *filename, int mode)

0 commit comments

Comments
 (0)