Skip to content

Commit

Permalink
fixup! Instead of creating Cygwin symlinks, use deep copy by default
Browse files Browse the repository at this point in the history
Allocate one WIN32_FIND_DATAW on the heap for the whole recursiveCopy,
to try to avoid running out of stack space before hitting path limit.
  • Loading branch information
jeremyd2019 committed Jan 31, 2025
1 parent ef41654 commit c8e2a8a
Showing 1 changed file with 22 additions and 13 deletions.
35 changes: 22 additions & 13 deletions winsup/cygwin/path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1693,14 +1693,20 @@ conv_path_list (const char *src, char *dst, size_t size,
Create a deep copy of src as dst, while avoiding descending in origpath.
*/
static int
recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath, PWIN32_FIND_DATAW dHfile = NULL)
{
WIN32_FIND_DATAW dHfile;
HANDLE dH = INVALID_HANDLE_VALUE;
NTSTATUS status;
int srcpos = src->Length;
int dstpos = dst->Length;
int res = -1;
bool freedHfile = false;

if (!dHfile)
{
dHfile = (PWIN32_FIND_DATAW) cmalloc_abort (HEAP_STR, sizeof (*dHfile));
freedHfile = true;
}

debug_printf ("recursiveCopy (%S, %S)", src, dst);

Expand Down Expand Up @@ -1736,7 +1742,7 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
goto done;
}

dH = FindFirstFileExW (src->Buffer, FindExInfoBasic, &dHfile,
dH = FindFirstFileExW (src->Buffer, FindExInfoBasic, dHfile,
FindExSearchNameMatch, NULL,
FIND_FIRST_EX_LARGE_FETCH);
if (dH == INVALID_HANDLE_VALUE)
Expand All @@ -1748,28 +1754,28 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
do
{
bool isdirlink = false;
debug_printf ("dHfile: %W", dHfile.cFileName);
if (dHfile.cFileName[0] == L'.' &&
(!dHfile.cFileName[1] ||
(dHfile.cFileName[1] == L'.' && !dHfile.cFileName[2])))
debug_printf ("dHfile: %W", dHfile->cFileName);
if (dHfile->cFileName[0] == L'.' &&
(!dHfile->cFileName[1] ||
(dHfile->cFileName[1] == L'.' && !dHfile->cFileName[2])))
continue;
/* Append the directory item filename to both source and destination */
src->Length = srcpos + sizeof (WCHAR);
dst->Length = dstpos + sizeof (WCHAR);
status = RtlAppendUnicodeToString (src, dHfile.cFileName);
status = RtlAppendUnicodeToString (src, dHfile->cFileName);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
goto done;
}
status = RtlAppendUnicodeToString (dst, dHfile.cFileName);
status = RtlAppendUnicodeToString (dst, dHfile->cFileName);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
goto done;
}
debug_printf ("%S -> %S", src, dst);
if ((dHfile.dwFileAttributes &
if ((dHfile->dwFileAttributes &
(FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_REPARSE_POINT)) ==
(FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_REPARSE_POINT))
{
Expand All @@ -1782,13 +1788,13 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
}
isdirlink = pc.issymlink ();
}
if ((dHfile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && !isdirlink)
if ((dHfile->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && !isdirlink)
{
/* Recurse into the child directory */
debug_printf ("%S <-> %W", src, origpath);
// avoids endless recursion
if (wcsncmp (src->Buffer, origpath, src->Length / sizeof (WCHAR)))
if (recursiveCopy (src, dst, origpath))
if (recursiveCopy (src, dst, origpath, dHfile))
goto done;
}
else
Expand All @@ -1803,7 +1809,7 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
}
}
}
while (FindNextFileW (dH, &dHfile));
while (FindNextFileW (dH, dHfile));

if (GetLastError() != ERROR_NO_MORE_FILES)
{
Expand All @@ -1817,6 +1823,9 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
if (dH != INVALID_HANDLE_VALUE)
FindClose (dH);

if (freedHfile)
cfree (dHfile);

return res;
}

Expand Down

0 comments on commit c8e2a8a

Please sign in to comment.