@@ -2012,7 +2012,7 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
20122012 path_conv win32_oldpath;
20132013 PUNICODE_STRING final_oldpath, final_newpath;
20142014 UNICODE_STRING final_oldpath_buf;
2015- DWORD flags;
2015+ DWORD flags = 0 ;
20162016
20172017 if (resolve_symlink_target (oldpath, win32_newpath, win32_oldpath))
20182018 final_oldpath = win32_oldpath.get_nt_native_path ();
@@ -2060,14 +2060,39 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
20602060 wcpcpy (e_old, c_old);
20612061 }
20622062 }
2063- /* If the symlink target doesn't exist, don't create native symlink.
2064- Otherwise the directory flag in the symlink is potentially wrong
2065- when the target comes into existence, and native tools will fail.
2066- This is so screwball. This is no problem on AFS, fortunately . */
2067- if (! win32_oldpath.exists () && ! win32_oldpath.fs_is_afs ())
2063+
2064+ /* The directory flag in the symlink must match the target type,
2065+ otherwise native tools will fail (fortunately this is no problem
2066+ on AFS). Do our best to guess the symlink type correctly . */
2067+ if (win32_oldpath.exists () || win32_oldpath.fs_is_afs ())
20682068 {
2069- SetLastError (ERROR_FILE_NOT_FOUND);
2070- return -1 ;
2069+ /* If the target exists (or on AFS), check the target type. Note
2070+ that this may still be wrong if the target is changed after
2071+ creating the symlink (e.g. in bulk operations such as rsync,
2072+ unpacking archives or VCS checkouts). */
2073+ if (win32_oldpath.isdir ())
2074+ flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
2075+ }
2076+ else
2077+ {
2078+ if (allow_winsymlinks == WSYM_nativestrict)
2079+ {
2080+ /* In nativestrict mode, if the target does not exist, use
2081+ trailing '/' in the target path as hint to create a
2082+ directory symlink. */
2083+ ssize_t len = strlen (oldpath);
2084+ if (len && isdirsep (oldpath[len - 1 ]))
2085+ flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
2086+ }
2087+ else
2088+ {
2089+ /* In native mode, if the target does not exist, fall back
2090+ to creating a Cygwin symlink file (or in case of MSys:
2091+ try to copy the (non-existing) target, which will of
2092+ course fail). */
2093+ SetLastError (ERROR_FILE_NOT_FOUND);
2094+ return -1 ;
2095+ }
20712096 }
20722097 /* Don't allow native symlinks to Cygwin special files. However, the
20732098 caller shoud know because this case shouldn't be covered by the
@@ -2096,7 +2121,6 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
20962121 final_oldpath->Buffer [1 ] = L' \\ ' ;
20972122 }
20982123 /* Try to create native symlink. */
2099- flags = win32_oldpath.isdir () ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0 ;
21002124 if (wincap.has_unprivileged_createsymlink ())
21012125 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
21022126 if (!CreateSymbolicLinkW (final_newpath->Buffer , final_oldpath->Buffer ,
0 commit comments