Cygwin: realpath: fix cygwin installation dir being access via junction
Consider this case: - Cygwin installed in C:\cygwin64 - mklink /j D:\cygwin64 C:\cygwin64 - create testcase calling realpath("/", result); printf ("%s\n", result); - start cmd >C:\cygwin64\bin\bash -lc <path-to-testcase> / >D\cygwin64\bin\bash -lc <path-to-testcase> /cygdrive/c/cygwin64 This scenario circumventing the mount point handling which is automated in terms of /, depending on the path returned from GetModuleFileNameW for the Cygwin DLL. When calling D:\cygwin64\bin\bash the dir returned from GetModuleFileNameW is D:\cygwin64\bin, thus root is D:\cygwin64. However, junctions are treated as symlinks in Cygwin which explains why the path gets converted to a cygdrive path. Fix this by calling GetFinalPathNameByHandleW on the result from GetModuleFileNameW to get the correct root path, even if accessed via a junction point. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
543e39bb12
commit
6d898f43fc
|
@ -144,6 +144,19 @@ init_cygheap::init_installation_root ()
|
||||||
api_fatal ("Can't initialize Cygwin installation root dir.\n"
|
api_fatal ("Can't initialize Cygwin installation root dir.\n"
|
||||||
"GetModuleFileNameW(%p, %p, %u), %E",
|
"GetModuleFileNameW(%p, %p, %u), %E",
|
||||||
cygwin_hmodule, installation_root_buf, PATH_MAX);
|
cygwin_hmodule, installation_root_buf, PATH_MAX);
|
||||||
|
|
||||||
|
/* We don't care if fetching the final pathname fails, it's non-fatal and
|
||||||
|
the path returned by GetModuleFileNameW is still valid. */
|
||||||
|
HANDLE h;
|
||||||
|
h = CreateFileW (installation_root_buf, GENERIC_READ, FILE_SHARE_VALID_FLAGS,
|
||||||
|
&sec_none, OPEN_EXISTING, 0, 0);
|
||||||
|
if (h != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
GetFinalPathNameByHandleW (h, installation_root_buf, PATH_MAX,
|
||||||
|
FILE_NAME_NORMALIZED);
|
||||||
|
CloseHandle (h);
|
||||||
|
}
|
||||||
|
|
||||||
PWCHAR p = installation_root_buf;
|
PWCHAR p = installation_root_buf;
|
||||||
if (wcsncasecmp (p, L"\\\\", 2)) /* Normal drive letter path */
|
if (wcsncasecmp (p, L"\\\\", 2)) /* Normal drive letter path */
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue