diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index 4e049211e9..955684e232 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -92,6 +92,8 @@ set_winsymlinks (const char *buf) ? WSYM_nativestrict : WSYM_native; else if (ascii_strncasematch (buf, "deepcopy", 8)) allow_winsymlinks = WSYM_deepcopy; + else if (ascii_strncasematch (buf, "nativeordeepcopy", 8)) + allow_winsymlinks = WSYM_native_or_deepcopy; else allow_winsymlinks = WSYM_sysfile; } diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc index ab2c205609..f05bdb753e 100644 --- a/winsup/cygwin/globals.cc +++ b/winsup/cygwin/globals.cc @@ -57,7 +57,8 @@ enum winsym_t WSYM_nativestrict, WSYM_nfs, WSYM_sysfile, - WSYM_deepcopy + WSYM_deepcopy, + WSYM_native_or_deepcopy }; exit_states NO_COPY exit_state; diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 8806e59c7d..0d912e26a3 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -2110,6 +2110,9 @@ symlink_worker (const char *oldpath, path_conv &win32_newpath, bool isdevice) else if ((wsym_type == WSYM_native || wsym_type == WSYM_nativestrict) && !(win32_newpath.fs_flags () & FILE_SUPPORTS_REPARSE_POINTS)) wsym_type = WSYM_default; + else if (wsym_type == WSYM_native_or_deepcopy + && !(win32_newpath.fs_flags () & FILE_SUPPORTS_REPARSE_POINTS)) + wsym_type = WSYM_deepcopy; /* Attach .lnk suffix when shortcut is requested. */ if (wsym_type == WSYM_lnk && !win32_newpath.exists () @@ -2144,6 +2147,7 @@ symlink_worker (const char *oldpath, path_conv &win32_newpath, bool isdevice) __leave; case WSYM_native: case WSYM_nativestrict: + case WSYM_native_or_deepcopy: res = symlink_native (oldpath, win32_newpath); if (!res) __leave; @@ -2154,6 +2158,12 @@ symlink_worker (const char *oldpath, path_conv &win32_newpath, bool isdevice) __seterrno (); __leave; } + /* With deepcopy fall back? Let's do that, then */ + if (res == -1 && wsym_type == WSYM_native_or_deepcopy) + { + wsym_type = WSYM_deepcopy; + break; + } /* Otherwise, fall back to default symlink type. */ wsym_type = WSYM_default; fallthrough; diff --git a/winsup/doc/cygwinenv.xml b/winsup/doc/cygwinenv.xml index c4e9f3f9e7..754a9c1cfb 100644 --- a/winsup/doc/cygwinenv.xml +++ b/winsup/doc/cygwinenv.xml @@ -104,7 +104,7 @@ back to the parent process. -winsymlinks:{lnk,native,nativestrict,sys,deepcopy} +winsymlinks:{lnk,native,nativestrict,sys,deepcopy,nativeordeepcopy} @@ -141,6 +141,14 @@ the source directory will be copied recursively). This mode makes a trade-off between compatibility and interoperability with Win32 programs, favoring the latter. + + +If set to winsymlinks:nativeordeepcopy Cygwin creates +symlinks as native Windows symlinks if supported (i.e. on file systems +supporting symbolic links, and when the current user is permitted to create +symbolic links, e.g. in Windows 10's "Developer Mode"), and fall back to +creating a deep copy in case symlinks are not supported. + Note that this setting has no effect where Cygwin knows that the