Skip to content

Commit 48205eb

Browse files
committed
squash! Do not create cygwin symlinks. Instead use deep copy of files/folders.
The original patch to change the symbolic link behavior to create deep copies instead did so in a bit of a hacky way: it used the `WSYM_sysfile` code path, not introducing a separate mode. This makes it impossible for users to ask for Cygwin's behavior (and it also poses a maintenance burden: for example, we had to specifically disable Cygwin's code to prefer to create WSL-style symlinks whenever possible instead of using the original Cygwin hack to use special-formed system files). Proposed new commit message when rebasing the MSYS2 patches on top of the next Cygwin runtime version: Instead of creating Cygwin symlinks, use deep copy by default The new `winsymlinks` mode `deepcopy` (which is made the default) lets calls to `symlink()` create (deep) copies of the source file/directory. This is necessary because unlike Cygwin, MSYS2 does not try to be its own little ecosystem that lives its life separate from regular Win32 programs: the latter have _no idea_ about Cygwin-emulated symbolic links (i.e. system files whose contents start with `!<symlink>\xff\xfe` and the remainder consists of the NUL-terminated, UTF-16LE-encoded symlink target). To support Cygwin-style symlinks, the new mode `sysfile` is introduced. Co-authored-by: Johannes Schindelin <[email protected]>
1 parent cfe1db3 commit 48205eb

File tree

3 files changed

+77
-69
lines changed

3 files changed

+77
-69
lines changed

winsup/cygwin/environ.cc

+4
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ set_winsymlinks (const char *buf)
8787
else if (ascii_strncasematch (buf, "native", 6))
8888
allow_winsymlinks = ascii_strcasematch (buf + 6, "strict")
8989
? WSYM_nativestrict : WSYM_native;
90+
else if (ascii_strncasematch (buf, "deepcopy", 8))
91+
allow_winsymlinks = WSYM_deepcopy;
92+
else
93+
allow_winsymlinks = WSYM_sysfile;
9094
}
9195

9296
/* The structure below is used to set up an array which is used to

winsup/cygwin/globals.cc

+3-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ enum winsym_t
5555
WSYM_lnk,
5656
WSYM_native,
5757
WSYM_nativestrict,
58-
WSYM_nfs
58+
WSYM_nfs,
59+
WSYM_deepcopy
5960
};
6061

6162
exit_states NO_COPY exit_state;
@@ -69,7 +70,7 @@ bool ignore_case_with_glob;
6970
bool pipe_byte;
7071
bool reset_com;
7172
bool wincmdln = true;
72-
winsym_t allow_winsymlinks = WSYM_sysfile;
73+
winsym_t allow_winsymlinks = WSYM_deepcopy;
7374
bool disable_pcon = true;
7475

7576
bool NO_COPY in_forkee;

winsup/cygwin/path.cc

+70-67
Original file line numberDiff line numberDiff line change
@@ -2269,73 +2269,76 @@ symlink_worker (const char *oldpath, path_conv &win32_newpath, bool isdevice)
22692269
}
22702270
else
22712271
{
2272-
path_conv src_path;
2273-
src_path.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
2274-
if (src_path.error)
2275-
{
2276-
set_errno (src_path.error);
2277-
__leave;
2278-
}
2279-
if (!src_path.isdevice () && !src_path.is_fs_special ())
2280-
{
2281-
/* MSYS copy file instead make symlink */
2282-
2283-
char * real_oldpath;
2284-
if (isabspath (oldpath))
2285-
strcpy (real_oldpath = tp.c_get (), oldpath);
2286-
else
2287-
/* Find the real source path, relative
2288-
to the directory of the destination */
2289-
{
2290-
/* Determine the character position of the last path component */
2291-
const char *newpath = win32_newpath.get_posix();
2292-
int pos = strlen (newpath);
2293-
while (--pos >= 0)
2294-
if (isdirsep (newpath[pos]))
2295-
break;
2296-
/* Append the source path to the directory
2297-
component of the destination */
2298-
if (pos+1+strlen(oldpath) >= MAX_PATH)
2299-
{
2300-
set_errno(ENAMETOOLONG);
2301-
__leave;
2302-
}
2303-
strcpy (real_oldpath = tp.c_get (), newpath);
2304-
strcpy (&real_oldpath[pos+1], oldpath);
2305-
}
2306-
2307-
/* As a MSYS limitation, the source path must exist. */
2308-
path_conv win32_oldpath;
2309-
win32_oldpath.check (real_oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
2310-
if (!win32_oldpath.exists ())
2311-
{
2312-
set_errno (ENOENT);
2313-
__leave;
2314-
}
2315-
2316-
char *w_newpath;
2317-
char *w_oldpath;
2318-
stpcpy (w_newpath = tp.c_get (), win32_newpath.get_win32());
2319-
stpcpy (w_oldpath = tp.c_get (), win32_oldpath.get_win32());
2320-
if (win32_oldpath.isdir())
2321-
{
2322-
char *origpath;
2323-
strcpy (origpath = tp.c_get (), w_oldpath);
2324-
res = recursiveCopy (w_oldpath, w_newpath, origpath);
2325-
}
2326-
else
2327-
{
2328-
if (!CopyFile (w_oldpath, w_newpath, FALSE))
2329-
{
2330-
__seterrno ();
2331-
}
2332-
else
2333-
{
2334-
res = 0;
2335-
}
2336-
}
2337-
__leave;
2338-
}
2272+
if (wsym_type == WSYM_deepcopy)
2273+
{
2274+
path_conv src_path;
2275+
src_path.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
2276+
if (src_path.error)
2277+
{
2278+
set_errno (src_path.error);
2279+
__leave;
2280+
}
2281+
if (!src_path.isdevice () && !src_path.is_fs_special ())
2282+
{
2283+
/* MSYS copy file instead make symlink */
2284+
2285+
char * real_oldpath;
2286+
if (isabspath (oldpath))
2287+
strcpy (real_oldpath = tp.c_get (), oldpath);
2288+
else
2289+
/* Find the real source path, relative
2290+
to the directory of the destination */
2291+
{
2292+
/* Determine the character position of the last path component */
2293+
const char *newpath = win32_newpath.get_posix();
2294+
int pos = strlen (newpath);
2295+
while (--pos >= 0)
2296+
if (isdirsep (newpath[pos]))
2297+
break;
2298+
/* Append the source path to the directory
2299+
component of the destination */
2300+
if (pos+1+strlen(oldpath) >= MAX_PATH)
2301+
{
2302+
set_errno(ENAMETOOLONG);
2303+
__leave;
2304+
}
2305+
strcpy (real_oldpath = tp.c_get (), newpath);
2306+
strcpy (&real_oldpath[pos+1], oldpath);
2307+
}
2308+
2309+
/* As a MSYS limitation, the source path must exist. */
2310+
path_conv win32_oldpath;
2311+
win32_oldpath.check (real_oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
2312+
if (!win32_oldpath.exists ())
2313+
{
2314+
set_errno (ENOENT);
2315+
__leave;
2316+
}
2317+
2318+
char *w_newpath;
2319+
char *w_oldpath;
2320+
stpcpy (w_newpath = tp.c_get (), win32_newpath.get_win32());
2321+
stpcpy (w_oldpath = tp.c_get (), win32_oldpath.get_win32());
2322+
if (win32_oldpath.isdir())
2323+
{
2324+
char *origpath;
2325+
strcpy (origpath = tp.c_get (), w_oldpath);
2326+
res = recursiveCopy (w_oldpath, w_newpath, origpath);
2327+
}
2328+
else
2329+
{
2330+
if (!CopyFile (w_oldpath, w_newpath, FALSE))
2331+
{
2332+
__seterrno ();
2333+
}
2334+
else
2335+
{
2336+
res = 0;
2337+
}
2338+
}
2339+
__leave;
2340+
}
2341+
}
23392342

23402343
/* Default technique creating a symlink. */
23412344
buf = tp.t_get ();

0 commit comments

Comments
 (0)