aboutsummaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorJeremy Drake via Cygwin-patches <cygwin-patches@cygwin.com>2025-02-03 11:38:48 -0800
committerCorinna Vinschen <corinna@vinschen.de>2025-02-03 23:02:21 +0100
commit5a706ff0fceb83fd1fe7f072fc28a741fdde65f2 (patch)
treeb07e13abd44daf9afa38e79b220a1e567cf2ef9d /winsup
parent0387c7e1ccef69787610e4a2c500f46513e51a6d (diff)
downloadnewlib-5a706ff0fceb83fd1fe7f072fc28a741fdde65f2.zip
newlib-5a706ff0fceb83fd1fe7f072fc28a741fdde65f2.tar.gz
newlib-5a706ff0fceb83fd1fe7f072fc28a741fdde65f2.tar.bz2
Cygwin: factor out code to resolve a symlink target.
This code was duplicated between the lnk symlink type and the native symlink type. Signed-off-by: Jeremy Drake <cygwin@jdrake.com>
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/path.cc62
1 files changed, 28 insertions, 34 deletions
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 658f3f9..d2aaed3 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -1756,6 +1756,31 @@ symlink (const char *oldpath, const char *newpath)
return -1;
}
+/* 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. */
+static bool
+resolve_symlink_target (const char *oldpath, const path_conv &win32_newpath,
+ path_conv &win32_oldpath)
+{
+ if (isabspath (oldpath))
+ {
+ win32_oldpath.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
+ return true;
+ }
+ else
+ {
+ tmp_pathbuf tp;
+ 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);
+ return false;
+ }
+}
+
static int
symlink_nfs (const char *oldpath, path_conv &win32_newpath)
{
@@ -1816,23 +1841,10 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
UNICODE_STRING final_oldpath_buf;
DWORD flags;
- if (isabspath (oldpath))
- {
- win32_oldpath.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
- final_oldpath = win32_oldpath.get_nt_native_path ();
- }
+ if (resolve_symlink_target (oldpath, win32_newpath, win32_oldpath))
+ final_oldpath = win32_oldpath.get_nt_native_path ();
else
{
- /* 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. */
- ssize_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);
-
/* Try hard to keep Windows symlink path relative. */
/* 1. Find common path prefix. Skip leading \\?\, but take pre-increment
@@ -2025,7 +2037,6 @@ int
symlink_worker (const char *oldpath, path_conv &win32_newpath, bool isdevice)
{
int res = -1;
- size_t len;
char *buf, *cp;
tmp_pathbuf tp;
winsym_t wsym_type;
@@ -2134,24 +2145,7 @@ symlink_worker (const char *oldpath, path_conv &win32_newpath, bool isdevice)
going to be. */
IShellFolder *psl;
- /* 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
- {
- 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);
- }
+ resolve_symlink_target (oldpath, win32_newpath, win32_oldpath);
if (SUCCEEDED (SHGetDesktopFolder (&psl)))
{
WCHAR wc_path[win32_oldpath.get_wide_win32_path_len () + 1];