Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

msys2-runtime: add deepcopy symlink improvements #5198

Merged
merged 1 commit into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
From 28d5757feb3049385071d96d55ed035dc485f07f Mon Sep 17 00:00:00 2001
From: Jeremy Drake <[email protected]>
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);
Loading