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
Add error handling.
  • Loading branch information
jeremyd2019 committed Jan 31, 2025
1 parent ab88228 commit ef41654
Showing 1 changed file with 50 additions and 9 deletions.
59 changes: 50 additions & 9 deletions winsup/cygwin/path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1697,6 +1697,7 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
{
WIN32_FIND_DATAW dHfile;
HANDLE dH = INVALID_HANDLE_VALUE;
NTSTATUS status;
int srcpos = src->Length;
int dstpos = dst->Length;
int res = -1;
Expand All @@ -1713,21 +1714,37 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
/* Descend into the source directory */
if (src->Buffer[(src->Length - 1) / sizeof (WCHAR)] != L'\\')
{
RtlAppendUnicodeToString (src, L"\\*");
status = RtlAppendUnicodeToString (src, L"\\*");
}
else
{
RtlAppendUnicodeToString (src, L"*");
status = RtlAppendUnicodeToString (src, L"*");
srcpos -= sizeof (WCHAR);
}
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
goto done;
}
if (dst->Buffer[(dst->Length - 1) / sizeof (WCHAR)] != L'\\')
RtlAppendUnicodeToString (dst, L"\\");
status = RtlAppendUnicodeToString (dst, L"\\");
else
dstpos -= sizeof (WCHAR);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
goto done;
}

dH = FindFirstFileExW (src->Buffer, FindExInfoBasic, &dHfile,
FindExSearchNameMatch, NULL,
FIND_FIRST_EX_LARGE_FETCH);
if (dH == INVALID_HANDLE_VALUE)
{
__seterrno ();
goto done;
}

do
{
bool isdirlink = false;
Expand All @@ -1739,15 +1756,30 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
/* Append the directory item filename to both source and destination */
src->Length = srcpos + sizeof (WCHAR);
dst->Length = dstpos + sizeof (WCHAR);
RtlAppendUnicodeToString (src, dHfile.cFileName);
RtlAppendUnicodeToString (dst, dHfile.cFileName);
status = RtlAppendUnicodeToString (src, dHfile.cFileName);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
goto done;
}
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 &
(FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_REPARSE_POINT)) ==
(FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_REPARSE_POINT))
{
/* this sucks hard */
path_conv pc (src, PC_SYM_NOFOLLOW|PC_SYM_NOFOLLOW_REP);
if (pc.error)
{
set_errno (pc.error);
goto done;
}
isdirlink = pc.issymlink ();
}
if ((dHfile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && !isdirlink)
Expand Down Expand Up @@ -2379,11 +2411,20 @@ symlink_worker (const char *oldpath, path_conv &win32_newpath, bool isdevice)
}
else
{
/* I don't know if there's a better way to know this */
DWORD attr = getfileattr (win32_oldpath.get_win32 (),
bool isdirlink = false;
if (win32_oldpath.issymlink () &&
win32_oldpath.is_known_reparse_point ())
{
/* Is there a better way to know this? */
DWORD attr = getfileattr (win32_oldpath.get_win32 (),
!!win32_oldpath.objcaseinsensitive ());
bool isdirlink = attr != INVALID_FILE_ATTRIBUTES &&
(attr & FILE_ATTRIBUTE_DIRECTORY);
if (attr == INVALID_FILE_ATTRIBUTES)
{
__seterrno ();
__leave;
}
isdirlink = attr & FILE_ATTRIBUTE_DIRECTORY;
}
if (!CopyFileExW (w_oldpath->Buffer, w_newpath->Buffer,
NULL, NULL, NULL,
COPY_FILE_COPY_SYMLINK|
Expand Down

0 comments on commit ef41654

Please sign in to comment.