Skip to content

Commit 4ee8a03

Browse files
committed
symlink_native: allow linking to ..
When running CYGWIN=winsymlinks:nativestrict ln -s .. abc the counter-intuitive result is _not_ a symbolic link to `..`, but instead to `../../$(basename "$PWD")`. The reason for this is that the search for the longest common prefix assumes that the link target is not a strict prefix of the parent directory of the link itself. Let's fix that. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 1f8def9 commit 4ee8a03

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

winsup/cygwin/path.cc

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2030,9 +2030,18 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
20302030
while (towupper (*++c_old) == towupper (*++c_new))
20312031
;
20322032
/* The last component could share a common prefix, so make sure we end
2033-
up on the first char after the last common backslash. */
2034-
while (c_old[-1] != L'\\')
2035-
--c_old, --c_new;
2033+
up on the first char after the last common backslash.
2034+
2035+
However, if c_old is a strict prefix of c_new (at a component
2036+
boundary), or vice versa, then do not try to find the last common
2037+
backslash. */
2038+
if ((!*c_old || *c_old == L'\\') && (!*c_new || *c_new == L'\\'))
2039+
c_old += !!*c_old, c_new += !!*c_new;
2040+
else
2041+
{
2042+
while (c_old[-1] != L'\\')
2043+
--c_old, --c_new;
2044+
}
20362045

20372046
/* 2. Check if prefix is long enough. The prefix must at least points to
20382047
a complete device: \\?\X:\ or \\?\UNC\server\share\ are the minimum
@@ -2057,8 +2066,10 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
20572066
final_oldpath = &final_oldpath_buf;
20582067
final_oldpath->Buffer = tp.w_get ();
20592068
PWCHAR e_old = final_oldpath->Buffer;
2060-
while (num-- > 0)
2061-
e_old = wcpcpy (e_old, L"..\\");
2069+
while (num > 1 || (num == 1 && *c_old))
2070+
e_old = wcpcpy (e_old, L"..\\"), num--;
2071+
if (num > 0)
2072+
e_old = wcpcpy (e_old, L"..");
20622073
wcpcpy (e_old, c_old);
20632074
}
20642075
}

0 commit comments

Comments
 (0)