@@ -1711,6 +1711,7 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
17111711 path_conv win32_oldpath;
17121712 PUNICODE_STRING final_oldpath, final_newpath;
17131713 UNICODE_STRING final_oldpath_buf;
1714+ bool isdir;
17141715
17151716 if (isabspath (oldpath))
17161717 {
@@ -1771,14 +1772,37 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
17711772 wcpcpy (e_old, c_old);
17721773 }
17731774 }
1774- /* If the symlink target doesn't exist, don't create native symlink.
1775- Otherwise the directory flag in the symlink is potentially wrong
1776- when the target comes into existence, and native tools will fail.
1777- This is so screwball. This is no problem on AFS, fortunately . */
1778- if (! win32_oldpath.exists () && ! win32_oldpath.fs_is_afs ())
1775+
1776+ /* The directory flag in the symlink must match the target type,
1777+ otherwise native tools will fail (fortunately this is no problem
1778+ on AFS). Do our best to guess the symlink type correctly . */
1779+ if (win32_oldpath.exists () || win32_oldpath.fs_is_afs ())
17791780 {
1780- SetLastError (ERROR_FILE_NOT_FOUND);
1781- return -1 ;
1781+ /* If the target exists (or on AFS), check the target type. Note
1782+ that this may still be wrong if the target is changed after
1783+ creating the symlink (e.g. in bulk operations such as rsync,
1784+ unpacking archives or VCS checkouts). */
1785+ isdir = win32_oldpath.isdir ();
1786+ }
1787+ else
1788+ {
1789+ if (allow_winsymlinks == WSYM_nativestrict)
1790+ {
1791+ /* In nativestrict mode, if the target does not exist, use
1792+ trailing '/' in the target path as hint to create a
1793+ directory symlink. */
1794+ ssize_t len = strlen (oldpath);
1795+ isdir = len && isdirsep (oldpath[len - 1 ]);
1796+ }
1797+ else
1798+ {
1799+ /* In native mode, if the target does not exist, fall back
1800+ to creating a Cygwin symlink file (or in case of MSys:
1801+ try to copy the (non-existing) target, which will of
1802+ course fail). */
1803+ SetLastError (ERROR_FILE_NOT_FOUND);
1804+ return -1 ;
1805+ }
17821806 }
17831807 /* Don't allow native symlinks to Cygwin special files. However, the
17841808 caller shoud know because this case shouldn't be covered by the
@@ -1809,8 +1833,7 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
18091833 }
18101834 /* Try to create native symlink. */
18111835 if (!CreateSymbolicLinkW (final_newpath->Buffer , final_oldpath->Buffer ,
1812- win32_oldpath.isdir ()
1813- ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0 ))
1836+ isdir ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0 ))
18141837 {
18151838 /* Repair native newpath, we still need it. */
18161839 final_newpath->Buffer [1 ] = L' ?' ;
0 commit comments