@@ -1689,6 +1689,7 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
16891689 path_conv win32_oldpath;
16901690 PUNICODE_STRING final_oldpath, final_newpath;
16911691 UNICODE_STRING final_oldpath_buf;
1692+ bool isdir;
16921693
16931694 if (isabspath (oldpath))
16941695 {
@@ -1749,14 +1750,37 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
17491750 wcpcpy (e_old, c_old);
17501751 }
17511752 }
1752- /* If the symlink target doesn't exist, don't create native symlink.
1753- Otherwise the directory flag in the symlink is potentially wrong
1754- when the target comes into existence, and native tools will fail.
1755- This is so screwball. This is no problem on AFS, fortunately . */
1756- if (! win32_oldpath.exists () && ! win32_oldpath.fs_is_afs ())
1753+
1754+ /* The directory flag in the symlink must match the target type,
1755+ otherwise native tools will fail (fortunately this is no problem
1756+ on AFS). Do our best to guess the symlink type correctly . */
1757+ if (win32_oldpath.exists () || win32_oldpath.fs_is_afs ())
17571758 {
1758- SetLastError (ERROR_FILE_NOT_FOUND);
1759- return -1 ;
1759+ /* If the target exists (or on AFS), check the target type. Note
1760+ that this may still be wrong if the target is changed after
1761+ creating the symlink (e.g. in bulk operations such as rsync,
1762+ unpacking archives or VCS checkouts). */
1763+ isdir = win32_oldpath.isdir ();
1764+ }
1765+ else
1766+ {
1767+ if (allow_winsymlinks == WSYM_nativestrict)
1768+ {
1769+ /* In nativestrict mode, if the target does not exist, use
1770+ trailing '/' in the target path as hint to create a
1771+ directory symlink. */
1772+ ssize_t len = strlen (oldpath);
1773+ isdir = len && isdirsep (oldpath[len - 1 ]);
1774+ }
1775+ else
1776+ {
1777+ /* In native mode, if the target does not exist, fall back
1778+ to creating a Cygwin symlink file (or in case of MSys:
1779+ try to copy the (non-existing) target, which will of
1780+ course fail). */
1781+ SetLastError (ERROR_FILE_NOT_FOUND);
1782+ return -1 ;
1783+ }
17601784 }
17611785 /* Don't allow native symlinks to Cygwin special files. However, the
17621786 caller shoud know because this case shouldn't be covered by the
@@ -1787,8 +1811,7 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
17871811 }
17881812 /* Try to create native symlink. */
17891813 if (!CreateSymbolicLinkW (final_newpath->Buffer , final_oldpath->Buffer ,
1790- win32_oldpath.isdir ()
1791- ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0 ))
1814+ isdir ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0 ))
17921815 {
17931816 /* Repair native newpath, we still need it. */
17941817 final_newpath->Buffer [1 ] = L' ?' ;
0 commit comments