@@ -1865,7 +1865,7 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
18651865 path_conv win32_oldpath;
18661866 PUNICODE_STRING final_oldpath, final_newpath;
18671867 UNICODE_STRING final_oldpath_buf;
1868- DWORD flags;
1868+ DWORD flags = 0 ;
18691869
18701870 if (isabspath (oldpath))
18711871 {
@@ -1926,14 +1926,39 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
19261926 wcpcpy (e_old, c_old);
19271927 }
19281928 }
1929- /* If the symlink target doesn't exist, don't create native symlink.
1930- Otherwise the directory flag in the symlink is potentially wrong
1931- when the target comes into existence, and native tools will fail.
1932- This is so screwball. This is no problem on AFS, fortunately . */
1933- if (! win32_oldpath.exists () && ! win32_oldpath.fs_is_afs ())
1929+
1930+ /* The directory flag in the symlink must match the target type,
1931+ otherwise native tools will fail (fortunately this is no problem
1932+ on AFS). Do our best to guess the symlink type correctly . */
1933+ if (win32_oldpath.exists () || win32_oldpath.fs_is_afs ())
19341934 {
1935- SetLastError (ERROR_FILE_NOT_FOUND);
1936- return -1 ;
1935+ /* If the target exists (or on AFS), check the target type. Note
1936+ that this may still be wrong if the target is changed after
1937+ creating the symlink (e.g. in bulk operations such as rsync,
1938+ unpacking archives or VCS checkouts). */
1939+ if (win32_oldpath.isdir ())
1940+ flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
1941+ }
1942+ else
1943+ {
1944+ if (allow_winsymlinks == WSYM_nativestrict)
1945+ {
1946+ /* In nativestrict mode, if the target does not exist, use
1947+ trailing '/' in the target path as hint to create a
1948+ directory symlink. */
1949+ ssize_t len = strlen (oldpath);
1950+ if (len && isdirsep (oldpath[len - 1 ]))
1951+ flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
1952+ }
1953+ else
1954+ {
1955+ /* In native mode, if the target does not exist, fall back
1956+ to creating a Cygwin symlink file (or in case of MSys:
1957+ try to copy the (non-existing) target, which will of
1958+ course fail). */
1959+ SetLastError (ERROR_FILE_NOT_FOUND);
1960+ return -1 ;
1961+ }
19371962 }
19381963 /* Don't allow native symlinks to Cygwin special files. However, the
19391964 caller shoud know because this case shouldn't be covered by the
@@ -1962,7 +1987,6 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
19621987 final_oldpath->Buffer [1 ] = L' \\ ' ;
19631988 }
19641989 /* Try to create native symlink. */
1965- flags = win32_oldpath.isdir () ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0 ;
19661990 if (wincap.has_unprivileged_createsymlink ())
19671991 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
19681992 if (!CreateSymbolicLinkW (final_newpath->Buffer , final_oldpath->Buffer ,
0 commit comments