msys2-runtime: add deepcopy symlink improvements
msys2/msys2-runtime#256
This commit is contained in:
committed by
Christoph Reiter
parent
b11b4ed895
commit
e5cebcadcc
@@ -0,0 +1,189 @@
|
||||
From 28d5757feb3049385071d96d55ed035dc485f07f Mon Sep 17 00:00:00 2001
|
||||
From: Jeremy Drake <github@jdrake.com>
|
||||
Date: Fri, 31 Jan 2025 16:00:56 -0800
|
||||
Subject: [PATCH 45/N] fixup! Instead of creating Cygwin symlinks, use deep
|
||||
copy by default
|
||||
|
||||
Factor out deepcopy symlink to its own worker function, like wsl,
|
||||
native, and nfs. Move it up into the beginning switch with them, so the
|
||||
fallback behavior is more obvious.
|
||||
---
|
||||
winsup/cygwin/path.cc | 151 ++++++++++++++++++++++--------------------
|
||||
1 file changed, 80 insertions(+), 71 deletions(-)
|
||||
|
||||
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
|
||||
index 661a688..cf582c7 100644
|
||||
--- a/winsup/cygwin/path.cc
|
||||
+++ b/winsup/cygwin/path.cc
|
||||
@@ -2072,6 +2072,79 @@ symlink_wsl (const char *oldpath, path_conv &win32_newpath)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int
|
||||
+symlink_deepcopy (const char *oldpath, path_conv &win32_newpath)
|
||||
+{
|
||||
+ tmp_pathbuf tp;
|
||||
+ path_conv src_path;
|
||||
+
|
||||
+ src_path.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
|
||||
+ if (src_path.error)
|
||||
+ {
|
||||
+ set_errno (src_path.error);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (src_path.isspecial ())
|
||||
+ return -2;
|
||||
+
|
||||
+ /* MSYS copy file instead make symlink */
|
||||
+ char * real_oldpath;
|
||||
+ if (isabspath (oldpath))
|
||||
+ strcpy (real_oldpath = tp.c_get (), oldpath);
|
||||
+ else
|
||||
+ /* Find the real source path, relative
|
||||
+ to the directory of the destination */
|
||||
+ {
|
||||
+ /* Determine the character position of the last path component */
|
||||
+ const char *newpath = win32_newpath.get_posix();
|
||||
+ int pos = strlen (newpath);
|
||||
+ while (--pos >= 0)
|
||||
+ if (isdirsep (newpath[pos]))
|
||||
+ break;
|
||||
+ /* Append the source path to the directory
|
||||
+ component of the destination */
|
||||
+ if (pos+1+strlen(oldpath) >= MAX_PATH)
|
||||
+ {
|
||||
+ set_errno(ENAMETOOLONG);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ strcpy (real_oldpath = tp.c_get (), newpath);
|
||||
+ strcpy (&real_oldpath[pos+1], oldpath);
|
||||
+ }
|
||||
+
|
||||
+ /* As a MSYS limitation, the source path must exist. */
|
||||
+ path_conv win32_oldpath;
|
||||
+ win32_oldpath.check (real_oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
|
||||
+ if (!win32_oldpath.exists ())
|
||||
+ {
|
||||
+ set_errno (ENOENT);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ char *w_newpath;
|
||||
+ char *w_oldpath;
|
||||
+ stpcpy (w_newpath = tp.c_get (), win32_newpath.get_win32());
|
||||
+ stpcpy (w_oldpath = tp.c_get (), win32_oldpath.get_win32());
|
||||
+ if (win32_oldpath.isdir())
|
||||
+ {
|
||||
+ char *origpath;
|
||||
+ strcpy (origpath = tp.c_get (), w_oldpath);
|
||||
+ return recursiveCopy (w_oldpath, w_newpath, origpath);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (!CopyFile (w_oldpath, w_newpath, FALSE))
|
||||
+ {
|
||||
+ __seterrno ();
|
||||
+ return -1;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
int
|
||||
symlink_worker (const char *oldpath, path_conv &win32_newpath, bool isdevice)
|
||||
{
|
||||
@@ -2140,6 +2213,13 @@ symlink_worker (const char *oldpath, path_conv &win32_newpath, bool isdevice)
|
||||
case WSYM_nfs:
|
||||
res = symlink_nfs (oldpath, win32_newpath);
|
||||
__leave;
|
||||
+ case WSYM_deepcopy:
|
||||
+ res = symlink_deepcopy (oldpath, win32_newpath);
|
||||
+ if (!res || res == -1)
|
||||
+ __leave;
|
||||
+ /* fall back to sysfile symlink type */
|
||||
+ wsym_type = WSYM_sysfile;
|
||||
+ break;
|
||||
case WSYM_native:
|
||||
case WSYM_nativestrict:
|
||||
res = symlink_native (oldpath, win32_newpath);
|
||||
@@ -2308,77 +2388,6 @@ symlink_worker (const char *oldpath, path_conv &win32_newpath, bool isdevice)
|
||||
}
|
||||
else /* wsym_type == WSYM_sysfile */
|
||||
{
|
||||
- if (wsym_type == WSYM_deepcopy)
|
||||
- {
|
||||
- path_conv src_path;
|
||||
- src_path.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
|
||||
- if (src_path.error)
|
||||
- {
|
||||
- set_errno (src_path.error);
|
||||
- __leave;
|
||||
- }
|
||||
- if (!src_path.isspecial ())
|
||||
- {
|
||||
- /* MSYS copy file instead make symlink */
|
||||
-
|
||||
- char * real_oldpath;
|
||||
- if (isabspath (oldpath))
|
||||
- strcpy (real_oldpath = tp.c_get (), oldpath);
|
||||
- else
|
||||
- /* Find the real source path, relative
|
||||
- to the directory of the destination */
|
||||
- {
|
||||
- /* Determine the character position of the last path component */
|
||||
- const char *newpath = win32_newpath.get_posix();
|
||||
- int pos = strlen (newpath);
|
||||
- while (--pos >= 0)
|
||||
- if (isdirsep (newpath[pos]))
|
||||
- break;
|
||||
- /* Append the source path to the directory
|
||||
- component of the destination */
|
||||
- if (pos+1+strlen(oldpath) >= MAX_PATH)
|
||||
- {
|
||||
- set_errno(ENAMETOOLONG);
|
||||
- __leave;
|
||||
- }
|
||||
- strcpy (real_oldpath = tp.c_get (), newpath);
|
||||
- strcpy (&real_oldpath[pos+1], oldpath);
|
||||
- }
|
||||
-
|
||||
- /* As a MSYS limitation, the source path must exist. */
|
||||
- path_conv win32_oldpath;
|
||||
- win32_oldpath.check (real_oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
|
||||
- if (!win32_oldpath.exists ())
|
||||
- {
|
||||
- set_errno (ENOENT);
|
||||
- __leave;
|
||||
- }
|
||||
-
|
||||
- char *w_newpath;
|
||||
- char *w_oldpath;
|
||||
- stpcpy (w_newpath = tp.c_get (), win32_newpath.get_win32());
|
||||
- stpcpy (w_oldpath = tp.c_get (), win32_oldpath.get_win32());
|
||||
- if (win32_oldpath.isdir())
|
||||
- {
|
||||
- char *origpath;
|
||||
- strcpy (origpath = tp.c_get (), w_oldpath);
|
||||
- res = recursiveCopy (w_oldpath, w_newpath, origpath);
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- if (!CopyFile (w_oldpath, w_newpath, FALSE))
|
||||
- {
|
||||
- __seterrno ();
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- res = 0;
|
||||
- }
|
||||
- }
|
||||
- __leave;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
/* Default technique creating a symlink. */
|
||||
buf = tp.t_get ();
|
||||
cp = stpcpy (buf, SYMLINK_COOKIE);
|
||||
@@ -0,0 +1,231 @@
|
||||
From 4606ccb4588d0993ca2351f3ed9e0e15f180e590 Mon Sep 17 00:00:00 2001
|
||||
From: Jeremy Drake <github@jdrake.com>
|
||||
Date: Thu, 30 Jan 2025 13:30:25 -0800
|
||||
Subject: [PATCH 46/N] fixup! Instead of creating Cygwin symlinks, use deep
|
||||
copy by default
|
||||
|
||||
Use unicode APIs instead of ANSI, for better handling of long paths and
|
||||
unicode characters.
|
||||
|
||||
Use FindFirstFileExW with FindExInfoBasic (because recursiveCopy doesn't
|
||||
care about short file names) and FIND_FIRST_EX_LARGE_FETCH (for better
|
||||
performance).
|
||||
|
||||
Use CopyFileExW with COPY_FILE_COPY_SYMLINK, so native symlinks act like
|
||||
sys and lnk file symlinks (they're copied as links instead of their
|
||||
target).
|
||||
---
|
||||
winsup/cygwin/path.cc | 144 +++++++++++++++++++++---------------------
|
||||
1 file changed, 72 insertions(+), 72 deletions(-)
|
||||
|
||||
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
|
||||
index cf582c7..9671e8f 100644
|
||||
--- a/winsup/cygwin/path.cc
|
||||
+++ b/winsup/cygwin/path.cc
|
||||
@@ -1693,69 +1693,75 @@ 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 (char * src, char * dst, const char * origpath)
|
||||
+recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
|
||||
{
|
||||
- WIN32_FIND_DATA dHfile;
|
||||
+ WIN32_FIND_DATAW dHfile;
|
||||
HANDLE dH = INVALID_HANDLE_VALUE;
|
||||
BOOL findfiles;
|
||||
- int srcpos = strlen (src);
|
||||
- int dstpos = strlen (dst);
|
||||
+ int srcpos = src->Length;
|
||||
+ int dstpos = dst->Length;
|
||||
int res = -1;
|
||||
|
||||
- debug_printf("recursiveCopy (%s, %s)", src, dst);
|
||||
+ debug_printf ("recursiveCopy (%S, %S)", src, dst);
|
||||
|
||||
/* Create the destination directory */
|
||||
- if (!CreateDirectoryEx (src, dst, NULL))
|
||||
+ if (!CreateDirectoryExW (src->Buffer, dst->Buffer, NULL))
|
||||
{
|
||||
- debug_printf("CreateDirectoryEx(%s, %s, 0) failed", src, dst);
|
||||
+ debug_printf ("CreateDirectoryExW(%S, %S, 0) failed", src, dst);
|
||||
__seterrno ();
|
||||
goto done;
|
||||
}
|
||||
/* Descend into the source directory */
|
||||
- if (srcpos + 2 >= MAX_PATH || dstpos + 1 >= MAX_PATH)
|
||||
+ if (src->Buffer[(src->Length - 1) / sizeof (WCHAR)] != L'\\')
|
||||
{
|
||||
- set_errno (ENAMETOOLONG);
|
||||
- goto done;
|
||||
+ RtlAppendUnicodeToString (src, L"\\*");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ RtlAppendUnicodeToString (src, L"*");
|
||||
+ srcpos -= sizeof (WCHAR);
|
||||
}
|
||||
- strcat (src, "\\*");
|
||||
- strcat (dst, "\\");
|
||||
- dH = FindFirstFile (src, &dHfile);
|
||||
- debug_printf("dHfile(1): %s", dHfile.cFileName);
|
||||
- findfiles = FindNextFile (dH, &dHfile);
|
||||
- debug_printf("dHfile(2): %s", dHfile.cFileName);
|
||||
- findfiles = FindNextFile (dH, &dHfile);
|
||||
+ if (dst->Buffer[(dst->Length - 1) / sizeof (WCHAR)] != L'\\')
|
||||
+ RtlAppendUnicodeToString (dst, L"\\");
|
||||
+ else
|
||||
+ dstpos -= sizeof (WCHAR);
|
||||
+
|
||||
+ dH = FindFirstFileExW (src->Buffer, FindExInfoBasic, &dHfile,
|
||||
+ FindExSearchNameMatch, NULL,
|
||||
+ FIND_FIRST_EX_LARGE_FETCH);
|
||||
+ debug_printf ("dHfile(1): %W", dHfile.cFileName);
|
||||
+ findfiles = FindNextFileW (dH, &dHfile);
|
||||
+ debug_printf ("dHfile(2): %W", dHfile.cFileName);
|
||||
+ findfiles = FindNextFileW (dH, &dHfile);
|
||||
while (findfiles)
|
||||
{
|
||||
/* Append the directory item filename to both source and destination */
|
||||
- int filelen = strlen (dHfile.cFileName);
|
||||
- debug_printf("dHfile(3): %s", dHfile.cFileName);
|
||||
- if (srcpos + 1 + filelen >= MAX_PATH ||
|
||||
- dstpos + 1 + filelen >= MAX_PATH)
|
||||
- {
|
||||
- set_errno (ENAMETOOLONG);
|
||||
- goto done;
|
||||
- }
|
||||
- strcpy (&src[srcpos+1], dHfile.cFileName);
|
||||
- strcpy (&dst[dstpos+1], dHfile.cFileName);
|
||||
- debug_printf("%s -> %s", src, dst);
|
||||
+ debug_printf ("dHfile(3): %W", dHfile.cFileName);
|
||||
+ src->Length = srcpos + sizeof (WCHAR);
|
||||
+ dst->Length = dstpos + sizeof (WCHAR);
|
||||
+ RtlAppendUnicodeToString (src, dHfile.cFileName);
|
||||
+ RtlAppendUnicodeToString (dst, dHfile.cFileName);
|
||||
+ debug_printf ("%S -> %S", src, dst);
|
||||
if (dHfile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
/* Recurse into the child directory */
|
||||
- debug_printf("%s <-> %s", src, origpath);
|
||||
- if (strcmp (src, origpath)) // avoids endless recursion
|
||||
+ debug_printf ("%S <-> %W", src, origpath);
|
||||
+ // avoids endless recursion
|
||||
+ if (wcsncmp (src->Buffer, origpath, src->Length / sizeof (WCHAR)))
|
||||
if (recursiveCopy (src, dst, origpath))
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Just copy the file */
|
||||
- if (!CopyFile (src, dst, FALSE))
|
||||
+ if (!CopyFileExW (src->Buffer, dst->Buffer, NULL, NULL, NULL,
|
||||
+ COPY_FILE_COPY_SYMLINK))
|
||||
{
|
||||
__seterrno ();
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
- findfiles = FindNextFile (dH, &dHfile);
|
||||
+ findfiles = FindNextFileW (dH, &dHfile);
|
||||
}
|
||||
if (GetLastError() != ERROR_NO_MORE_FILES)
|
||||
{
|
||||
@@ -2076,64 +2082,58 @@ int
|
||||
symlink_deepcopy (const char *oldpath, path_conv &win32_newpath)
|
||||
{
|
||||
tmp_pathbuf tp;
|
||||
- path_conv src_path;
|
||||
+ path_conv win32_oldpath;
|
||||
|
||||
- src_path.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
|
||||
- if (src_path.error)
|
||||
+ /* The symlink target is relative to the directory in which the
|
||||
+ symlink gets created, not relative to the cwd. Therefore we
|
||||
+ have to mangle the path quite a bit before calling path_conv.*/
|
||||
+ if (isabspath (oldpath))
|
||||
+ win32_oldpath.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
|
||||
+ else
|
||||
{
|
||||
- set_errno (src_path.error);
|
||||
+ size_t len = strrchr (win32_newpath.get_posix (), '/')
|
||||
+ - win32_newpath.get_posix () + 1;
|
||||
+ char *absoldpath = tp.t_get ();
|
||||
+ stpcpy (stpncpy (absoldpath, win32_newpath.get_posix (), len),
|
||||
+ oldpath);
|
||||
+ win32_oldpath.check (absoldpath, PC_SYM_NOFOLLOW, stat_suffixes);
|
||||
+ }
|
||||
+ if (win32_oldpath.error)
|
||||
+ {
|
||||
+ set_errno (win32_oldpath.error);
|
||||
return -1;
|
||||
}
|
||||
- if (src_path.isspecial ())
|
||||
+ if (win32_oldpath.isspecial ())
|
||||
return -2;
|
||||
|
||||
/* MSYS copy file instead make symlink */
|
||||
- char * real_oldpath;
|
||||
- if (isabspath (oldpath))
|
||||
- strcpy (real_oldpath = tp.c_get (), oldpath);
|
||||
- else
|
||||
- /* Find the real source path, relative
|
||||
- to the directory of the destination */
|
||||
- {
|
||||
- /* Determine the character position of the last path component */
|
||||
- const char *newpath = win32_newpath.get_posix();
|
||||
- int pos = strlen (newpath);
|
||||
- while (--pos >= 0)
|
||||
- if (isdirsep (newpath[pos]))
|
||||
- break;
|
||||
- /* Append the source path to the directory
|
||||
- component of the destination */
|
||||
- if (pos+1+strlen(oldpath) >= MAX_PATH)
|
||||
- {
|
||||
- set_errno(ENAMETOOLONG);
|
||||
- return -1;
|
||||
- }
|
||||
- strcpy (real_oldpath = tp.c_get (), newpath);
|
||||
- strcpy (&real_oldpath[pos+1], oldpath);
|
||||
- }
|
||||
-
|
||||
/* As a MSYS limitation, the source path must exist. */
|
||||
- path_conv win32_oldpath;
|
||||
- win32_oldpath.check (real_oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
|
||||
if (!win32_oldpath.exists ())
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
- char *w_newpath;
|
||||
- char *w_oldpath;
|
||||
- stpcpy (w_newpath = tp.c_get (), win32_newpath.get_win32());
|
||||
- stpcpy (w_oldpath = tp.c_get (), win32_oldpath.get_win32());
|
||||
- if (win32_oldpath.isdir())
|
||||
+ PUNICODE_STRING w_oldpath = win32_oldpath.get_nt_native_path ();
|
||||
+ PUNICODE_STRING w_newpath = win32_newpath.get_nt_native_path ();
|
||||
+ if (w_oldpath->Buffer[1] == L'?')
|
||||
+ w_oldpath->Buffer[1] = L'\\';
|
||||
+ if (w_newpath->Buffer[1] == L'?')
|
||||
+ w_newpath->Buffer[1] = L'\\';
|
||||
+ if (win32_oldpath.isdir ())
|
||||
{
|
||||
- char *origpath;
|
||||
- strcpy (origpath = tp.c_get (), w_oldpath);
|
||||
- return recursiveCopy (w_oldpath, w_newpath, origpath);
|
||||
+ PWCHAR origpath = win32_oldpath.get_wide_win32_path (tp.w_get ());
|
||||
+ /* we need a larger UNICODE_STRING MaximumLength than
|
||||
+ get_nt_native_path allocates for the recursive copy */
|
||||
+ UNICODE_STRING u_oldpath, u_newpath;
|
||||
+ RtlCopyUnicodeString (tp.u_get (&u_oldpath), w_oldpath);
|
||||
+ RtlCopyUnicodeString (tp.u_get (&u_newpath), w_newpath);
|
||||
+ return recursiveCopy (&u_oldpath, &u_newpath, origpath);
|
||||
}
|
||||
else
|
||||
{
|
||||
- if (!CopyFile (w_oldpath, w_newpath, FALSE))
|
||||
+ if (!CopyFileExW (w_oldpath->Buffer, w_newpath->Buffer,
|
||||
+ NULL, NULL, NULL, COPY_FILE_COPY_SYMLINK))
|
||||
{
|
||||
__seterrno ();
|
||||
return -1;
|
||||
@@ -0,0 +1,136 @@
|
||||
From 4fa86d82cb1bb74c86014f4f4331c19262bc7fd9 Mon Sep 17 00:00:00 2001
|
||||
From: Jeremy Drake <github@jdrake.com>
|
||||
Date: Thu, 30 Jan 2025 14:39:18 -0800
|
||||
Subject: [PATCH 47/N] fixup! Instead of creating Cygwin symlinks, use deep
|
||||
copy by default
|
||||
|
||||
Don't attempt to recurse into directory symlinks, but instead copy them
|
||||
as symlinks.
|
||||
|
||||
Use CreateDirectoryEx to copy directory reparse points (directory
|
||||
symlinks or junctions). This seems to work at least back to 8.1, unlike
|
||||
the COPY_FILE_DIRECTORY flag, which was introduced in 19041.
|
||||
---
|
||||
winsup/cygwin/path.cc | 86 ++++++++++++++++++++++++++++++++-----------
|
||||
1 file changed, 65 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
|
||||
index 9671e8f..dfbbdaa 100644
|
||||
--- a/winsup/cygwin/path.cc
|
||||
+++ b/winsup/cygwin/path.cc
|
||||
@@ -1735,6 +1735,7 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
|
||||
findfiles = FindNextFileW (dH, &dHfile);
|
||||
while (findfiles)
|
||||
{
|
||||
+ bool isdirlink = false;
|
||||
/* Append the directory item filename to both source and destination */
|
||||
debug_printf ("dHfile(3): %W", dHfile.cFileName);
|
||||
src->Length = srcpos + sizeof (WCHAR);
|
||||
@@ -1742,25 +1743,44 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
|
||||
RtlAppendUnicodeToString (src, dHfile.cFileName);
|
||||
RtlAppendUnicodeToString (dst, dHfile.cFileName);
|
||||
debug_printf ("%S -> %S", src, dst);
|
||||
- if (dHfile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
+ 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);
|
||||
+ isdirlink = pc.issymlink ();
|
||||
+ }
|
||||
+ if (isdirlink)
|
||||
{
|
||||
- /* Recurse into the child directory */
|
||||
- debug_printf ("%S <-> %W", src, origpath);
|
||||
+ /* CreateDirectoryEx seems to "copy" directory reparse points, which
|
||||
+ CopyFileEx can only do with a flag introduced in 19041. */
|
||||
+ if (!CreateDirectoryExW (src->Buffer, dst->Buffer, NULL))
|
||||
+ {
|
||||
+ debug_printf ("CreateDirectoryExW(%S, %S, 0) failed", src, dst);
|
||||
+ __seterrno ();
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+ else if (dHfile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
+ {
|
||||
+ /* 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))
|
||||
- goto done;
|
||||
- }
|
||||
+ if (wcsncmp (src->Buffer, origpath, src->Length / sizeof (WCHAR)))
|
||||
+ if (recursiveCopy (src, dst, origpath))
|
||||
+ goto done;
|
||||
+ }
|
||||
else
|
||||
- {
|
||||
- /* Just copy the file */
|
||||
- if (!CopyFileExW (src->Buffer, dst->Buffer, NULL, NULL, NULL,
|
||||
+ {
|
||||
+ /* Just copy the file */
|
||||
+ if (!CopyFileExW (src->Buffer, dst->Buffer, NULL, NULL, NULL,
|
||||
COPY_FILE_COPY_SYMLINK))
|
||||
- {
|
||||
- __seterrno ();
|
||||
- goto done;
|
||||
- }
|
||||
- }
|
||||
+ {
|
||||
+ __seterrno ();
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
findfiles = FindNextFileW (dH, &dHfile);
|
||||
}
|
||||
if (GetLastError() != ERROR_NO_MORE_FILES)
|
||||
@@ -2132,17 +2152,41 @@ symlink_deepcopy (const char *oldpath, path_conv &win32_newpath)
|
||||
}
|
||||
else
|
||||
{
|
||||
- if (!CopyFileExW (w_oldpath->Buffer, w_newpath->Buffer,
|
||||
- NULL, NULL, NULL, COPY_FILE_COPY_SYMLINK))
|
||||
+ bool isdirlink = false;
|
||||
+ if (win32_oldpath.issymlink () &&
|
||||
+ win32_oldpath.is_known_reparse_point ())
|
||||
{
|
||||
- __seterrno ();
|
||||
- return -1;
|
||||
+ /* Is there a better way to know this? */
|
||||
+ DWORD attr = getfileattr (win32_oldpath.get_win32 (),
|
||||
+ !!win32_oldpath.objcaseinsensitive ());
|
||||
+ if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
+ {
|
||||
+ __seterrno ();
|
||||
+ return -1;
|
||||
+ }
|
||||
+ isdirlink = attr & FILE_ATTRIBUTE_DIRECTORY;
|
||||
}
|
||||
- else
|
||||
+ if (isdirlink)
|
||||
+ {
|
||||
+ /* CreateDirectoryEx seems to "copy" directory reparse points, which
|
||||
+ CopyFileEx can only do with a flag introduced in 19041. */
|
||||
+ if (!CreateDirectoryExW (w_oldpath->Buffer, w_newpath->Buffer, NULL))
|
||||
+ {
|
||||
+ debug_printf ("CreateDirectoryExW(%S, %S, 0) failed", w_oldpath,
|
||||
+ w_newpath);
|
||||
+ __seterrno ();
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+ else if (!CopyFileExW (w_oldpath->Buffer, w_newpath->Buffer, NULL, NULL,
|
||||
+ NULL, COPY_FILE_COPY_SYMLINK))
|
||||
{
|
||||
- return 0;
|
||||
+ __seterrno ();
|
||||
+ return -1;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -0,0 +1,57 @@
|
||||
From ed1c4f3322f115bd9a8e9306014d50bc41ad467b Mon Sep 17 00:00:00 2001
|
||||
From: Jeremy Drake <github@jdrake.com>
|
||||
Date: Thu, 30 Jan 2025 17:45:16 -0800
|
||||
Subject: [PATCH 48/N] fixup! Instead of creating Cygwin symlinks, use deep
|
||||
copy by default
|
||||
|
||||
Don't assume the first two entries are always `.` and `..`. On the root
|
||||
of a volume, those don't seem to be present.
|
||||
---
|
||||
winsup/cygwin/path.cc | 16 ++++++++--------
|
||||
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
|
||||
index dfbbdaa..1e6baef 100644
|
||||
--- a/winsup/cygwin/path.cc
|
||||
+++ b/winsup/cygwin/path.cc
|
||||
@@ -1697,7 +1697,6 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
|
||||
{
|
||||
WIN32_FIND_DATAW dHfile;
|
||||
HANDLE dH = INVALID_HANDLE_VALUE;
|
||||
- BOOL findfiles;
|
||||
int srcpos = src->Length;
|
||||
int dstpos = dst->Length;
|
||||
int res = -1;
|
||||
@@ -1729,15 +1728,15 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
|
||||
dH = FindFirstFileExW (src->Buffer, FindExInfoBasic, &dHfile,
|
||||
FindExSearchNameMatch, NULL,
|
||||
FIND_FIRST_EX_LARGE_FETCH);
|
||||
- debug_printf ("dHfile(1): %W", dHfile.cFileName);
|
||||
- findfiles = FindNextFileW (dH, &dHfile);
|
||||
- debug_printf ("dHfile(2): %W", dHfile.cFileName);
|
||||
- findfiles = FindNextFileW (dH, &dHfile);
|
||||
- while (findfiles)
|
||||
+ 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])))
|
||||
+ continue;
|
||||
/* Append the directory item filename to both source and destination */
|
||||
- debug_printf ("dHfile(3): %W", dHfile.cFileName);
|
||||
src->Length = srcpos + sizeof (WCHAR);
|
||||
dst->Length = dstpos + sizeof (WCHAR);
|
||||
RtlAppendUnicodeToString (src, dHfile.cFileName);
|
||||
@@ -1781,8 +1780,9 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
- findfiles = FindNextFileW (dH, &dHfile);
|
||||
}
|
||||
+ while (FindNextFileW (dH, &dHfile));
|
||||
+
|
||||
if (GetLastError() != ERROR_NO_MORE_FILES)
|
||||
{
|
||||
__seterrno ();
|
||||
@@ -0,0 +1,97 @@
|
||||
From b581e48de68ede7ac406b4c03d297822ce9e4613 Mon Sep 17 00:00:00 2001
|
||||
From: Jeremy Drake <github@jdrake.com>
|
||||
Date: Thu, 30 Jan 2025 22:00:06 -0800
|
||||
Subject: [PATCH 49/N] fixup! Instead of creating Cygwin symlinks, use deep
|
||||
copy by default
|
||||
|
||||
Add error handling.
|
||||
---
|
||||
winsup/cygwin/path.cc | 42 +++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 37 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
|
||||
index 1e6baef..56f9d6a 100644
|
||||
--- a/winsup/cygwin/path.cc
|
||||
+++ b/winsup/cygwin/path.cc
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -1739,8 +1756,18 @@ 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)) ==
|
||||
@@ -1748,6 +1775,11 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
|
||||
{
|
||||
/* 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 (isdirlink)
|
||||
@@ -0,0 +1,155 @@
|
||||
From e5effeec3bb1bbfd4849b03c92a7cc2ff3b146a7 Mon Sep 17 00:00:00 2001
|
||||
From: Jeremy Drake <github@jdrake.com>
|
||||
Date: Fri, 31 Jan 2025 10:33:27 -0800
|
||||
Subject: [PATCH 50/N] fixup! Instead of creating Cygwin symlinks, use deep
|
||||
copy by default
|
||||
|
||||
Allocate one WIN32_FIND_DATAW on the heap for the whole recursiveCopy,
|
||||
to avoid running out of stack space before hitting path limit.
|
||||
|
||||
Move the path_conv object into its own function to avoid it being in the
|
||||
recursion's stack frame.
|
||||
---
|
||||
winsup/cygwin/path.cc | 61 ++++++++++++++++++++++++++++---------------
|
||||
1 file changed, 40 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
|
||||
index 56f9d6a..4a9d500 100644
|
||||
--- a/winsup/cygwin/path.cc
|
||||
+++ b/winsup/cygwin/path.cc
|
||||
@@ -1689,18 +1689,37 @@ conv_path_list (const char *src, char *dst, size_t size,
|
||||
|
||||
/********************** Symbolic Link Support **************************/
|
||||
|
||||
+static int
|
||||
+recursiveCopyCheckSymlink(PUNICODE_STRING src, bool& isdirlink)
|
||||
+{
|
||||
+ path_conv pc (src, PC_SYM_NOFOLLOW|PC_SYM_NOFOLLOW_REP);
|
||||
+ if (pc.error)
|
||||
+ {
|
||||
+ set_errno (pc.error);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ isdirlink = pc.issymlink ();
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
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);
|
||||
|
||||
@@ -1736,7 +1755,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)
|
||||
@@ -1748,39 +1767,36 @@ 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))
|
||||
{
|
||||
- /* 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 ();
|
||||
+ /* I was really hoping to avoid using path_conv in the recursion,
|
||||
+ but maybe putting it in its own function will prevent it from
|
||||
+ taking up space in the stack frame */
|
||||
+ if (recursiveCopyCheckSymlink (src, isdirlink))
|
||||
+ goto done;
|
||||
}
|
||||
if (isdirlink)
|
||||
{
|
||||
@@ -1793,13 +1809,13 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
- else if (dHfile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
+ else if (dHfile->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
/* 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
|
||||
@@ -1813,7 +1829,7 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath)
|
||||
}
|
||||
}
|
||||
}
|
||||
- while (FindNextFileW (dH, &dHfile));
|
||||
+ while (FindNextFileW (dH, dHfile));
|
||||
|
||||
if (GetLastError() != ERROR_NO_MORE_FILES)
|
||||
{
|
||||
@@ -1827,6 +1843,9 @@ done:
|
||||
if (dH != INVALID_HANDLE_VALUE)
|
||||
FindClose (dH);
|
||||
|
||||
+ if (freedHfile)
|
||||
+ cfree (dHfile);
|
||||
+
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
From cf77c3eff0ddd18e9182928e346a70618064a281 Mon Sep 17 00:00:00 2001
|
||||
From: Jeremy Drake <github@jdrake.com>
|
||||
Date: Fri, 31 Jan 2025 12:27:42 -0800
|
||||
Subject: [PATCH 51/N] fixup! Instead of creating Cygwin symlinks, use deep
|
||||
copy by default
|
||||
|
||||
avoid recursing into dst as well as src. Given we only ever append to
|
||||
either, their original lengths should be sufficient, rather than copies
|
||||
of them.
|
||||
---
|
||||
winsup/cygwin/path.cc | 19 ++++++++++++-------
|
||||
1 file changed, 12 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
|
||||
index 4a9d500..373aec9 100644
|
||||
--- a/winsup/cygwin/path.cc
|
||||
+++ b/winsup/cygwin/path.cc
|
||||
@@ -1706,7 +1706,8 @@ recursiveCopyCheckSymlink(PUNICODE_STRING src, bool& isdirlink)
|
||||
Create a deep copy of src as dst, while avoiding descending in origpath.
|
||||
*/
|
||||
static int
|
||||
-recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath, PWIN32_FIND_DATAW dHfile = NULL)
|
||||
+recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, USHORT origsrclen,
|
||||
+ USHORT origdstlen, PWIN32_FIND_DATAW dHfile = NULL)
|
||||
{
|
||||
HANDLE dH = INVALID_HANDLE_VALUE;
|
||||
NTSTATUS status;
|
||||
@@ -1812,11 +1813,15 @@ recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, PCWSTR origpath, PWIN32
|
||||
else if (dHfile->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
/* 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, dHfile))
|
||||
+ /* avoids endless recursion */
|
||||
+ if (src->Length <= origsrclen ||
|
||||
+ !wcsncmp (src->Buffer, dst->Buffer, origdstlen / sizeof (WCHAR)))
|
||||
+ {
|
||||
+ set_errno (ELOOP);
|
||||
goto done;
|
||||
+ }
|
||||
+ if (recursiveCopy (src, dst, origsrclen, origdstlen, dHfile))
|
||||
+ goto done;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2193,13 +2198,13 @@ symlink_deepcopy (const char *oldpath, path_conv &win32_newpath)
|
||||
w_newpath->Buffer[1] = L'\\';
|
||||
if (win32_oldpath.isdir ())
|
||||
{
|
||||
- PWCHAR origpath = win32_oldpath.get_wide_win32_path (tp.w_get ());
|
||||
/* we need a larger UNICODE_STRING MaximumLength than
|
||||
get_nt_native_path allocates for the recursive copy */
|
||||
UNICODE_STRING u_oldpath, u_newpath;
|
||||
RtlCopyUnicodeString (tp.u_get (&u_oldpath), w_oldpath);
|
||||
RtlCopyUnicodeString (tp.u_get (&u_newpath), w_newpath);
|
||||
- return recursiveCopy (&u_oldpath, &u_newpath, origpath);
|
||||
+ return recursiveCopy (&u_oldpath, &u_newpath,
|
||||
+ u_oldpath.Length, u_newpath.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -0,0 +1,49 @@
|
||||
From 19b50e4bbb3f833ed43d16741d15735bd5fe682b Mon Sep 17 00:00:00 2001
|
||||
From: Jeremy Drake <github@jdrake.com>
|
||||
Date: Tue, 4 Feb 2025 11:05:18 -0800
|
||||
Subject: [PATCH 52/N] amend! Instead of creating Cygwin symlinks, use deep
|
||||
copy by default
|
||||
|
||||
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 <johannes.schindelin@gmx.de>
|
||||
Co-authored-by: Jeremy Drake <github@jdrake.com>
|
||||
---
|
||||
winsup/cygwin/path.cc | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
|
||||
index 373aec9..33eb644 100644
|
||||
--- a/winsup/cygwin/path.cc
|
||||
+++ b/winsup/cygwin/path.cc
|
||||
@@ -2160,6 +2160,10 @@ symlink_deepcopy (const char *oldpath, path_conv &win32_newpath)
|
||||
tmp_pathbuf tp;
|
||||
path_conv win32_oldpath;
|
||||
|
||||
+ /* **BEGIN** replace this with
|
||||
+ resolve_symlink_target (oldpath, win32_newpath. win32_oldpath);
|
||||
+ when rebasing over 5a706ff0fceb83fd1fe7f072fc28a741fdde65f2
|
||||
+ (probably Cygwin 3.6) */
|
||||
/* The symlink target is relative to the directory in which the
|
||||
symlink gets created, not relative to the cwd. Therefore we
|
||||
have to mangle the path quite a bit before calling path_conv.*/
|
||||
@@ -2174,6 +2178,7 @@ symlink_deepcopy (const char *oldpath, path_conv &win32_newpath)
|
||||
oldpath);
|
||||
win32_oldpath.check (absoldpath, PC_SYM_NOFOLLOW, stat_suffixes);
|
||||
}
|
||||
+ /* **END** */
|
||||
if (win32_oldpath.error)
|
||||
{
|
||||
set_errno (win32_oldpath.error);
|
||||
@@ -4,7 +4,7 @@
|
||||
pkgbase=msys2-runtime
|
||||
pkgname=('msys2-runtime' 'msys2-runtime-devel')
|
||||
pkgver=3.5.7
|
||||
pkgrel=1
|
||||
pkgrel=2
|
||||
pkgdesc="Cygwin POSIX emulation engine"
|
||||
arch=('x86_64')
|
||||
url="https://www.cygwin.com/"
|
||||
@@ -72,7 +72,15 @@ source=('msys2-runtime'::git://sourceware.org/git/newlib-cygwin.git#tag=cygwin-$
|
||||
0041-cygthread-suspend-thread-before-terminating.patch
|
||||
0042-Cygwin-revert-use-of-CancelSyncronousIo-on-wait_thre.patch
|
||||
0043-Cygwin-cache-IsWow64Process2-host-arch-in-wincap.patch
|
||||
0044-Cygwin-uname-add-host-machine-tag-to-sysname.patch)
|
||||
0044-Cygwin-uname-add-host-machine-tag-to-sysname.patch
|
||||
0045-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch
|
||||
0046-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch
|
||||
0047-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch
|
||||
0048-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch
|
||||
0049-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch
|
||||
0050-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch
|
||||
0051-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch
|
||||
0052-amend-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch)
|
||||
sha256sums=('e78e129eed8e2dd4a2600fe6df8cb6f3beb9dca786574823ed55951adecb7064'
|
||||
'87d86c95008274731cf560d929ae5fb319d962591303b2690e11bfd60f4818e7'
|
||||
'c6d091cb51440638eb9fc59b35ba40f2b63e9e32a31a56c51a2aaec2445aa88e'
|
||||
@@ -117,7 +125,15 @@ sha256sums=('e78e129eed8e2dd4a2600fe6df8cb6f3beb9dca786574823ed55951adecb7064'
|
||||
'94c5ed183b0fd2d9efaecd839bee8d25621c01d8ba2f32d3a98e958936c73fec'
|
||||
'e1d1779b1c14897ee8543f14d54383bf9313e407cde74da217fbfe21c92ac4fc'
|
||||
'6c6e23ece7fa055d27289bad39d0007623303673316c593feba15fb6cfaf2b8a'
|
||||
'9aefd148000fbfaebfd8a490cd980efb43e9a6b000002df11be6a4eacfb43365')
|
||||
'9aefd148000fbfaebfd8a490cd980efb43e9a6b000002df11be6a4eacfb43365'
|
||||
'734b7f1e1264834817a42ebe83cf2bda06417e0ebb1090c6eecd267f420de043'
|
||||
'f7a54cd5328c909f907dfc1766a3192b22fd80195504f8989c8c0dc220da8a24'
|
||||
'73243bedf4918b8e9bc0f033444c95d1eac89824c4efacab33b19d383a6799fd'
|
||||
'26318aa2f84e7f28400695cd79b71c499dda72043a50483e6263115bc8ec53fd'
|
||||
'0d438fbe0aa08c01a9f10547ced185d42d3583ff835dbb768dd687249138fb99'
|
||||
'e24911a237886d043959ccf64a4f862e91b0d9e322f200d255355040aae3ea16'
|
||||
'54e01260a3b481f2e178f2d603442d206b497b554a530c85d365febb11b12488'
|
||||
'086916ec5e3f038d6b815f268880bdda39b574efaa1c9a53fdc08ce46a57ba20')
|
||||
|
||||
# Helper macros to help make tasks easier #
|
||||
apply_patch_with_msg() {
|
||||
@@ -198,7 +214,15 @@ prepare() {
|
||||
0041-cygthread-suspend-thread-before-terminating.patch \
|
||||
0042-Cygwin-revert-use-of-CancelSyncronousIo-on-wait_thre.patch \
|
||||
0043-Cygwin-cache-IsWow64Process2-host-arch-in-wincap.patch \
|
||||
0044-Cygwin-uname-add-host-machine-tag-to-sysname.patch
|
||||
0044-Cygwin-uname-add-host-machine-tag-to-sysname.patch \
|
||||
0045-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch \
|
||||
0046-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch \
|
||||
0047-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch \
|
||||
0048-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch \
|
||||
0049-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch \
|
||||
0050-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch \
|
||||
0051-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch \
|
||||
0052-amend-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch
|
||||
}
|
||||
|
||||
build() {
|
||||
|
||||
Reference in New Issue
Block a user