Skip to content

Commit 8b4557b

Browse files
committed
fixup! Instead of creating Cygwin symlinks, use deep copy by default
factor out duplicated code to mangle a relative symlink target.
1 parent 965fb2d commit 8b4557b

File tree

1 file changed

+31
-46
lines changed

1 file changed

+31
-46
lines changed

winsup/cygwin/path.cc

Lines changed: 31 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,31 @@ symlink (const char *oldpath, const char *newpath)
18791879
return -1;
18801880
}
18811881

1882+
static bool
1883+
mangle_symlink_target (const char *oldpath, const path_conv &win32_newpath,
1884+
path_conv &win32_oldpath)
1885+
{
1886+
/* The symlink target is relative to the directory in which the
1887+
symlink gets created, not relative to the cwd. Therefore we
1888+
have to mangle the path quite a bit before calling path_conv.*/
1889+
if (isabspath (oldpath))
1890+
{
1891+
win32_oldpath.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
1892+
return true;
1893+
}
1894+
else
1895+
{
1896+
tmp_pathbuf tp;
1897+
size_t len = strrchr (win32_newpath.get_posix (), '/')
1898+
- win32_newpath.get_posix () + 1;
1899+
char *absoldpath = tp.t_get ();
1900+
stpcpy (stpncpy (absoldpath, win32_newpath.get_posix (), len),
1901+
oldpath);
1902+
win32_oldpath.check (absoldpath, PC_SYM_NOFOLLOW, stat_suffixes);
1903+
return false;
1904+
}
1905+
}
1906+
18821907
static int
18831908
symlink_nfs (const char *oldpath, path_conv &win32_newpath)
18841909
{
@@ -1939,23 +1964,10 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
19391964
UNICODE_STRING final_oldpath_buf;
19401965
DWORD flags;
19411966

1942-
if (isabspath (oldpath))
1943-
{
1944-
win32_oldpath.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
1945-
final_oldpath = win32_oldpath.get_nt_native_path ();
1946-
}
1967+
if (mangle_symlink_target (oldpath, win32_newpath, win32_oldpath))
1968+
final_oldpath = win32_oldpath.get_nt_native_path ();
19471969
else
19481970
{
1949-
/* The symlink target is relative to the directory in which
1950-
the symlink gets created, not relative to the cwd. Therefore
1951-
we have to mangle the path quite a bit before calling path_conv. */
1952-
ssize_t len = strrchr (win32_newpath.get_posix (), '/')
1953-
- win32_newpath.get_posix () + 1;
1954-
char *absoldpath = tp.t_get ();
1955-
stpcpy (stpncpy (absoldpath, win32_newpath.get_posix (), len),
1956-
oldpath);
1957-
win32_oldpath.check (absoldpath, PC_SYM_NOFOLLOW, stat_suffixes);
1958-
19591971
/* Try hard to keep Windows symlink path relative. */
19601972

19611973
/* 1. Find common path prefix. Skip leading \\?\, but take pre-increment
@@ -2260,21 +2272,7 @@ symlink_worker (const char *oldpath, path_conv &win32_newpath, bool isdevice)
22602272
/* The symlink target is relative to the directory in which the
22612273
symlink gets created, not relative to the cwd. Therefore we
22622274
have to mangle the path quite a bit before calling path_conv.*/
2263-
if (isabspath (oldpath))
2264-
win32_oldpath.check (oldpath,
2265-
PC_SYM_NOFOLLOW,
2266-
stat_suffixes);
2267-
else
2268-
{
2269-
len = strrchr (win32_newpath.get_posix (), '/')
2270-
- win32_newpath.get_posix () + 1;
2271-
char *absoldpath = tp.t_get ();
2272-
stpcpy (stpncpy (absoldpath, win32_newpath.get_posix (),
2273-
len),
2274-
oldpath);
2275-
win32_oldpath.check (absoldpath, PC_SYM_NOFOLLOW,
2276-
stat_suffixes);
2277-
}
2275+
mangle_symlink_target (oldpath, win32_newpath, win32_oldpath);
22782276
if (SUCCEEDED (SHGetDesktopFolder (&psl)))
22792277
{
22802278
WCHAR wc_path[win32_oldpath.get_wide_win32_path_len () + 1];
@@ -2378,29 +2376,15 @@ symlink_worker (const char *oldpath, path_conv &win32_newpath, bool isdevice)
23782376
* sizeof (WCHAR);
23792377
cp += *plen;
23802378
}
2381-
else /* wsym_type == WSYM_sysfile */
2379+
else
23822380
{
23832381
if (wsym_type == WSYM_deepcopy)
23842382
{
23852383
path_conv win32_oldpath;
23862384
/* The symlink target is relative to the directory in which the
23872385
symlink gets created, not relative to the cwd. Therefore we
23882386
have to mangle the path quite a bit before calling path_conv.*/
2389-
if (isabspath (oldpath))
2390-
win32_oldpath.check (oldpath,
2391-
PC_SYM_NOFOLLOW,
2392-
stat_suffixes);
2393-
else
2394-
{
2395-
len = strrchr (win32_newpath.get_posix (), '/')
2396-
- win32_newpath.get_posix () + 1;
2397-
char *absoldpath = tp.t_get ();
2398-
stpcpy (stpncpy (absoldpath, win32_newpath.get_posix (),
2399-
len),
2400-
oldpath);
2401-
win32_oldpath.check (absoldpath, PC_SYM_NOFOLLOW,
2402-
stat_suffixes);
2403-
}
2387+
mangle_symlink_target (oldpath, win32_newpath, win32_oldpath);
24042388
if (win32_oldpath.error)
24052389
{
24062390
set_errno (win32_oldpath.error);
@@ -2464,6 +2448,7 @@ symlink_worker (const char *oldpath, path_conv &win32_newpath, bool isdevice)
24642448
}
24652449
}
24662450

2451+
/* wsym_type == WSYM_sysfile */
24672452
/* Default technique creating a symlink. */
24682453
buf = tp.t_get ();
24692454
cp = stpcpy (buf, SYMLINK_COOKIE);

0 commit comments

Comments
 (0)