Skip to content

Commit d771eaf

Browse files
Alexpuxlazka
authored andcommitted
Do not create cygwin symlinks. Instead use deep copy of files/folders.
1 parent d340694 commit d771eaf

File tree

1 file changed

+147
-0
lines changed

1 file changed

+147
-0
lines changed

winsup/cygwin/path.cc

+147
Original file line numberDiff line numberDiff line change
@@ -1643,6 +1643,86 @@ conv_path_list (const char *src, char *dst, size_t size,
16431643

16441644
/********************** Symbolic Link Support **************************/
16451645

1646+
/*
1647+
Create a deep copy of src as dst, while avoiding descending in origpath.
1648+
*/
1649+
static int
1650+
recursiveCopy (char * src, char * dst, const char * origpath)
1651+
{
1652+
WIN32_FIND_DATA dHfile;
1653+
HANDLE dH;
1654+
BOOL findfiles;
1655+
int srcpos = strlen (src);
1656+
int dstpos = strlen (dst);
1657+
int res = -1;
1658+
1659+
debug_printf("recursiveCopy (%s, %s)", src, dst);
1660+
1661+
/* Create the destination directory */
1662+
if (!CreateDirectoryEx (src, dst, NULL))
1663+
{
1664+
debug_printf("CreateDirectoryEx(%s, %s, 0) failed", src, dst);
1665+
__seterrno ();
1666+
goto done;
1667+
}
1668+
/* Descend into the source directory */
1669+
if (srcpos + 2 >= MAX_PATH || dstpos + 1 >= MAX_PATH)
1670+
{
1671+
set_errno (ENAMETOOLONG);
1672+
goto done;
1673+
}
1674+
strcat (src, "\\*");
1675+
strcat (dst, "\\");
1676+
dH = FindFirstFile (src, &dHfile);
1677+
debug_printf("dHfile(1): %s", dHfile.cFileName);
1678+
findfiles = FindNextFile (dH, &dHfile);
1679+
debug_printf("dHfile(2): %s", dHfile.cFileName);
1680+
findfiles = FindNextFile (dH, &dHfile);
1681+
while (findfiles)
1682+
{
1683+
/* Append the directory item filename to both source and destination */
1684+
int filelen = strlen (dHfile.cFileName);
1685+
debug_printf("dHfile(3): %s", dHfile.cFileName);
1686+
if (srcpos + 1 + filelen >= MAX_PATH ||
1687+
dstpos + 1 + filelen >= MAX_PATH)
1688+
{
1689+
set_errno (ENAMETOOLONG);
1690+
goto done;
1691+
}
1692+
strcpy (&src[srcpos+1], dHfile.cFileName);
1693+
strcpy (&dst[dstpos+1], dHfile.cFileName);
1694+
debug_printf("%s -> %s", src, dst);
1695+
if (dHfile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1696+
{
1697+
/* Recurse into the child directory */
1698+
debug_printf("%s <-> %s", src, origpath);
1699+
if (strcmp (src, origpath)) // avoids endless recursion
1700+
if (recursiveCopy (src, dst, origpath))
1701+
goto done;
1702+
}
1703+
else
1704+
{
1705+
/* Just copy the file */
1706+
if (!CopyFile (src, dst, FALSE))
1707+
{
1708+
__seterrno ();
1709+
goto done;
1710+
}
1711+
}
1712+
findfiles = FindNextFile (dH, &dHfile);
1713+
}
1714+
if (GetLastError() != ERROR_NO_MORE_FILES)
1715+
{
1716+
__seterrno ();
1717+
goto done;
1718+
}
1719+
res = 0;
1720+
1721+
done:
1722+
1723+
return res;
1724+
}
1725+
16461726
/* Create a symlink from FROMPATH to TOPATH. */
16471727

16481728
extern "C" int
@@ -2175,6 +2255,73 @@ symlink_worker (const char *oldpath, path_conv &win32_newpath, bool isdevice)
21752255
}
21762256
else
21772257
{
2258+
path_conv src_path;
2259+
src_path.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
2260+
if (src_path.error)
2261+
{
2262+
set_errno (src_path.error);
2263+
__leave;
2264+
}
2265+
if (!src_path.isdevice () && !src_path.is_fs_special ())
2266+
{
2267+
/* MSYS copy file instead make symlink */
2268+
2269+
char * real_oldpath;
2270+
if (isabspath (oldpath))
2271+
strcpy (real_oldpath = tp.c_get (), oldpath);
2272+
else
2273+
/* Find the real source path, relative
2274+
to the directory of the destination */
2275+
{
2276+
/* Determine the character position of the last path component */
2277+
int pos = strlen (newpath);
2278+
while (--pos >= 0)
2279+
if (isdirsep (newpath[pos]))
2280+
break;
2281+
/* Append the source path to the directory
2282+
component of the destination */
2283+
if (pos+1+strlen(oldpath) >= MAX_PATH)
2284+
{
2285+
set_errno(ENAMETOOLONG);
2286+
__leave;
2287+
}
2288+
strcpy (real_oldpath = tp.c_get (), newpath);
2289+
strcpy (&real_oldpath[pos+1], oldpath);
2290+
}
2291+
2292+
/* As a MSYS limitation, the source path must exist. */
2293+
path_conv win32_oldpath;
2294+
win32_oldpath.check (real_oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
2295+
if (!win32_oldpath.exists ())
2296+
{
2297+
set_errno (ENOENT);
2298+
__leave;
2299+
}
2300+
2301+
char *w_newpath;
2302+
char *w_oldpath;
2303+
stpcpy (w_newpath = tp.c_get (), win32_newpath.get_win32());
2304+
stpcpy (w_oldpath = tp.c_get (), win32_oldpath.get_win32());
2305+
if (win32_oldpath.isdir())
2306+
{
2307+
char *origpath;
2308+
strcpy (origpath = tp.c_get (), w_oldpath);
2309+
res = recursiveCopy (w_oldpath, w_newpath, origpath);
2310+
}
2311+
else
2312+
{
2313+
if (!CopyFile (w_oldpath, w_newpath, FALSE))
2314+
{
2315+
__seterrno ();
2316+
}
2317+
else
2318+
{
2319+
res = 0;
2320+
}
2321+
}
2322+
__leave;
2323+
}
2324+
21782325
/* Default technique creating a symlink. */
21792326
buf = tp.t_get ();
21802327
cp = stpcpy (buf, SYMLINK_COOKIE);

0 commit comments

Comments
 (0)