@@ -2014,7 +2014,7 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
20142014 path_conv win32_oldpath;
20152015 PUNICODE_STRING final_oldpath, final_newpath;
20162016 UNICODE_STRING final_oldpath_buf;
2017- DWORD flags;
2017+ DWORD flags = 0 ;
20182018
20192019 if (resolve_symlink_target (oldpath, win32_newpath, win32_oldpath))
20202020 final_oldpath = win32_oldpath.get_nt_native_path ();
@@ -2073,14 +2073,39 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
20732073 wcpcpy (e_old, c_old);
20742074 }
20752075 }
2076- /* If the symlink target doesn't exist, don't create native symlink.
2077- Otherwise the directory flag in the symlink is potentially wrong
2078- when the target comes into existence, and native tools will fail.
2079- This is so screwball. This is no problem on AFS, fortunately . */
2080- if (! win32_oldpath.exists () && ! win32_oldpath.fs_is_afs ())
2076+
2077+ /* The directory flag in the symlink must match the target type,
2078+ otherwise native tools will fail (fortunately this is no problem
2079+ on AFS). Do our best to guess the symlink type correctly . */
2080+ if (win32_oldpath.exists () || win32_oldpath.fs_is_afs ())
20812081 {
2082- SetLastError (ERROR_FILE_NOT_FOUND);
2083- return -1 ;
2082+ /* If the target exists (or on AFS), check the target type. Note
2083+ that this may still be wrong if the target is changed after
2084+ creating the symlink (e.g. in bulk operations such as rsync,
2085+ unpacking archives or VCS checkouts). */
2086+ if (win32_oldpath.isdir ())
2087+ flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
2088+ }
2089+ else
2090+ {
2091+ if (allow_winsymlinks == WSYM_nativestrict)
2092+ {
2093+ /* In nativestrict mode, if the target does not exist, use
2094+ trailing '/' in the target path as hint to create a
2095+ directory symlink. */
2096+ ssize_t len = strlen (oldpath);
2097+ if (len && isdirsep (oldpath[len - 1 ]))
2098+ flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
2099+ }
2100+ else
2101+ {
2102+ /* In native mode, if the target does not exist, fall back
2103+ to creating a Cygwin symlink file (or in case of MSys:
2104+ try to copy the (non-existing) target, which will of
2105+ course fail). */
2106+ SetLastError (ERROR_FILE_NOT_FOUND);
2107+ return -1 ;
2108+ }
20842109 }
20852110 /* Don't allow native symlinks to Cygwin special files. However, the
20862111 caller shoud know because this case shouldn't be covered by the
@@ -2109,7 +2134,6 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
21092134 final_oldpath->Buffer [1 ] = L' \\ ' ;
21102135 }
21112136 /* Try to create native symlink. */
2112- flags = win32_oldpath.isdir () ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0 ;
21132137 if (wincap.has_unprivileged_createsymlink ())
21142138 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
21152139 if (!CreateSymbolicLinkW (final_newpath->Buffer , final_oldpath->Buffer ,
0 commit comments