190 lines
5.3 KiB
Diff
190 lines
5.3 KiB
Diff
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);
|