@@ -1879,7 +1879,7 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
1879
1879
path_conv win32_oldpath;
1880
1880
PUNICODE_STRING final_oldpath, final_newpath;
1881
1881
UNICODE_STRING final_oldpath_buf;
1882
- DWORD flags;
1882
+ DWORD flags = 0 ;
1883
1883
1884
1884
if (isabspath (oldpath))
1885
1885
{
@@ -1940,14 +1940,39 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
1940
1940
wcpcpy (e_old, c_old);
1941
1941
}
1942
1942
}
1943
- /* If the symlink target doesn't exist, don't create native symlink.
1944
- Otherwise the directory flag in the symlink is potentially wrong
1945
- when the target comes into existence, and native tools will fail.
1946
- This is so screwball. This is no problem on AFS, fortunately . */
1947
- if (! win32_oldpath.exists () && ! win32_oldpath.fs_is_afs ())
1943
+
1944
+ /* The directory flag in the symlink must match the target type,
1945
+ otherwise native tools will fail (fortunately this is no problem
1946
+ on AFS). Do our best to guess the symlink type correctly . */
1947
+ if (win32_oldpath.exists () || win32_oldpath.fs_is_afs ())
1948
1948
{
1949
- SetLastError (ERROR_FILE_NOT_FOUND);
1950
- return -1 ;
1949
+ /* If the target exists (or on AFS), check the target type. Note
1950
+ that this may still be wrong if the target is changed after
1951
+ creating the symlink (e.g. in bulk operations such as rsync,
1952
+ unpacking archives or VCS checkouts). */
1953
+ if (win32_oldpath.isdir ())
1954
+ flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
1955
+ }
1956
+ else
1957
+ {
1958
+ if (allow_winsymlinks == WSYM_nativestrict)
1959
+ {
1960
+ /* In nativestrict mode, if the target does not exist, use
1961
+ trailing '/' in the target path as hint to create a
1962
+ directory symlink. */
1963
+ ssize_t len = strlen (oldpath);
1964
+ if (len && isdirsep (oldpath[len - 1 ]))
1965
+ flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
1966
+ }
1967
+ else
1968
+ {
1969
+ /* In native mode, if the target does not exist, fall back
1970
+ to creating a Cygwin symlink file (or in case of MSys:
1971
+ try to copy the (non-existing) target, which will of
1972
+ course fail). */
1973
+ SetLastError (ERROR_FILE_NOT_FOUND);
1974
+ return -1 ;
1975
+ }
1951
1976
}
1952
1977
/* Don't allow native symlinks to Cygwin special files. However, the
1953
1978
caller shoud know because this case shouldn't be covered by the
@@ -1976,7 +2001,6 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
1976
2001
final_oldpath->Buffer [1 ] = L' \\ ' ;
1977
2002
}
1978
2003
/* Try to create native symlink. */
1979
- flags = win32_oldpath.isdir () ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0 ;
1980
2004
if (wincap.has_unprivileged_createsymlink ())
1981
2005
flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
1982
2006
if (!CreateSymbolicLinkW (final_newpath->Buffer , final_oldpath->Buffer ,
0 commit comments