Skip to content

Commit

Permalink
msys2-runtime: add deepcopy symlink improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremyd2019 authored and lazka committed Feb 6, 2025
1 parent b11b4ed commit e5cebca
Show file tree
Hide file tree
Showing 9 changed files with 1,005 additions and 4 deletions.
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

0 comments on commit e5cebca

Please sign in to comment.