@@ -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+
18821907static int
18831908symlink_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