Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a winsymlinks mode that prefers native symlinks, falling back to the deep copy mode #114

Open
wants to merge 2 commits into
base: msys2-3.5.3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions winsup/cygwin/environ.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
3 changes: 2 additions & 1 deletion winsup/cygwin/globals.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 10 additions & 0 deletions winsup/cygwin/path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 ()
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
18 changes: 17 additions & 1 deletion winsup/doc/cygwinenv.xml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ back to the parent process.</para>
</listitem>

<listitem>
<para><envar>winsymlinks:{lnk,native,nativestrict,sys}</envar></para>
<para><envar>winsymlinks:{lnk,native,nativestrict,sys,deepcopy,nativeordeepcopy}</envar></para>

<itemizedlist mark="square">
<listitem>
Expand Down Expand Up @@ -133,6 +133,22 @@ system call will immediately fail.</para>
plain files with the <literal>system</literal> attribute, containing a magic
cookie followed by the path to which the link points.</para>
</listitem>

<listitem>
<para>If set to <literal>winsymlinks:deepcopy</literal>, a copy of the source
will be created at the target (a "deep" copy in the case of directories, i.e.
the source directory will be copied recursively). This mode makes a trade-off
between compatibility and interoperability with Win32 programs, favoring the
latter.</para>
</listitem>

<listitem>
<para>If set to <literal>winsymlinks:nativeordeepcopy</literal> 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.</para>
</listitem>
</itemizedlist>

<para>Note that this setting has no effect where Cygwin knows that the
Expand Down
Loading