Skip to content

Commit 6a80caf

Browse files
committed
Do not create cygwin symlinks. Instead use deep copy of files/folders.
1 parent 0aa606e commit 6a80caf

File tree

1 file changed

+147
-0
lines changed

1 file changed

+147
-0
lines changed

winsup/cygwin/path.cc

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,86 @@ conv_path_list (const char *src, char *dst, size_t size,
15711571

15721572
/********************** Symbolic Link Support **************************/
15731573

1574+
/*
1575+
Create a deep copy of src as dst, while avoiding descending in origpath.
1576+
*/
1577+
static int
1578+
recursiveCopy (char * src, char * dst, const char * origpath)
1579+
{
1580+
WIN32_FIND_DATA dHfile;
1581+
HANDLE dH;
1582+
BOOL findfiles;
1583+
int srcpos = strlen (src);
1584+
int dstpos = strlen (dst);
1585+
int res = -1;
1586+
1587+
debug_printf("recursiveCopy (%s, %s)", src, dst);
1588+
1589+
/* Create the destination directory */
1590+
if (!CreateDirectoryEx (src, dst, NULL))
1591+
{
1592+
debug_printf("CreateDirectoryEx(%s, %s, 0) failed", src, dst);
1593+
__seterrno ();
1594+
goto done;
1595+
}
1596+
/* Descend into the source directory */
1597+
if (srcpos + 2 >= MAX_PATH || dstpos + 1 >= MAX_PATH)
1598+
{
1599+
set_errno (ENAMETOOLONG);
1600+
goto done;
1601+
}
1602+
strcat (src, "\\*");
1603+
strcat (dst, "\\");
1604+
dH = FindFirstFile (src, &dHfile);
1605+
debug_printf("dHfile(1): %s", dHfile.cFileName);
1606+
findfiles = FindNextFile (dH, &dHfile);
1607+
debug_printf("dHfile(2): %s", dHfile.cFileName);
1608+
findfiles = FindNextFile (dH, &dHfile);
1609+
while (findfiles)
1610+
{
1611+
/* Append the directory item filename to both source and destination */
1612+
int filelen = strlen (dHfile.cFileName);
1613+
debug_printf("dHfile(3): %s", dHfile.cFileName);
1614+
if (srcpos + 1 + filelen >= MAX_PATH ||
1615+
dstpos + 1 + filelen >= MAX_PATH)
1616+
{
1617+
set_errno (ENAMETOOLONG);
1618+
goto done;
1619+
}
1620+
strcpy (&src[srcpos+1], dHfile.cFileName);
1621+
strcpy (&dst[dstpos+1], dHfile.cFileName);
1622+
debug_printf("%s -> %s", src, dst);
1623+
if (dHfile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1624+
{
1625+
/* Recurse into the child directory */
1626+
debug_printf("%s <-> %s", src, origpath);
1627+
if (strcmp (src, origpath)) // avoids endless recursion
1628+
if (recursiveCopy (src, dst, origpath))
1629+
goto done;
1630+
}
1631+
else
1632+
{
1633+
/* Just copy the file */
1634+
if (!CopyFile (src, dst, FALSE))
1635+
{
1636+
__seterrno ();
1637+
goto done;
1638+
}
1639+
}
1640+
findfiles = FindNextFile (dH, &dHfile);
1641+
}
1642+
if (GetLastError() != ERROR_NO_MORE_FILES)
1643+
{
1644+
__seterrno ();
1645+
goto done;
1646+
}
1647+
res = 0;
1648+
1649+
done:
1650+
1651+
return res;
1652+
}
1653+
15741654
/* Create a symlink from FROMPATH to TOPATH. */
15751655

15761656
extern "C" int
@@ -1995,6 +2075,73 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
19952075
}
19962076
else
19972077
{
2078+
path_conv src_path;
2079+
src_path.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
2080+
if (src_path.error)
2081+
{
2082+
set_errno (src_path.error);
2083+
__leave;
2084+
}
2085+
if (!src_path.isdevice () && !src_path.is_fs_special ())
2086+
{
2087+
/* MSYS copy file instead make symlink */
2088+
2089+
char * real_oldpath;
2090+
if (isabspath (oldpath))
2091+
strcpy (real_oldpath = tp.c_get (), oldpath);
2092+
else
2093+
/* Find the real source path, relative
2094+
to the directory of the destination */
2095+
{
2096+
/* Determine the character position of the last path component */
2097+
int pos = strlen (newpath);
2098+
while (--pos >= 0)
2099+
if (isdirsep (newpath[pos]))
2100+
break;
2101+
/* Append the source path to the directory
2102+
component of the destination */
2103+
if (pos+1+strlen(oldpath) >= MAX_PATH)
2104+
{
2105+
set_errno(ENAMETOOLONG);
2106+
__leave;
2107+
}
2108+
strcpy (real_oldpath = tp.c_get (), newpath);
2109+
strcpy (&real_oldpath[pos+1], oldpath);
2110+
}
2111+
2112+
/* As a MSYS limitation, the source path must exist. */
2113+
path_conv win32_oldpath;
2114+
win32_oldpath.check (real_oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
2115+
if (!win32_oldpath.exists ())
2116+
{
2117+
set_errno (ENOENT);
2118+
__leave;
2119+
}
2120+
2121+
char *w_newpath;
2122+
char *w_oldpath;
2123+
stpcpy (w_newpath = tp.c_get (), win32_newpath.get_win32());
2124+
stpcpy (w_oldpath = tp.c_get (), win32_oldpath.get_win32());
2125+
if (win32_oldpath.isdir())
2126+
{
2127+
char *origpath;
2128+
strcpy (origpath = tp.c_get (), w_oldpath);
2129+
res = recursiveCopy (w_oldpath, w_newpath, origpath);
2130+
}
2131+
else
2132+
{
2133+
if (!CopyFile (w_oldpath, w_newpath, FALSE))
2134+
{
2135+
__seterrno ();
2136+
}
2137+
else
2138+
{
2139+
res = 0;
2140+
}
2141+
}
2142+
__leave;
2143+
}
2144+
19982145
/* Default technique creating a symlink. */
19992146
buf = tp.t_get ();
20002147
cp = stpcpy (buf, SYMLINK_COOKIE);

0 commit comments

Comments
 (0)