mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-28 12:05:47 +08:00
* path.cc (cnt_bs): New inline function.
(symlink_native): Fix creating relative native symlink.
This commit is contained in:
parent
42c8e85109
commit
2566c2e600
@ -1,3 +1,8 @@
|
|||||||
|
2013-06-17 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* path.cc (cnt_bs): New inline function.
|
||||||
|
(symlink_native): Fix creating relative native symlink.
|
||||||
|
|
||||||
2013-06-17 Corinna Vinschen <corinna@vinschen.de>
|
2013-06-17 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_clipboard.cc (fhandler_dev_clipboard::read): Fix buffer
|
* fhandler_clipboard.cc (fhandler_dev_clipboard::read): Fix buffer
|
||||||
|
@ -1530,12 +1530,25 @@ symlink_nfs (const char *oldpath, path_conv &win32_newpath)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Count backslashes between s and e. */
|
||||||
|
static inline int
|
||||||
|
cnt_bs (PWCHAR s, PWCHAR e)
|
||||||
|
{
|
||||||
|
int num = 0;
|
||||||
|
|
||||||
|
while (s < e)
|
||||||
|
if (*s++ == L'\\')
|
||||||
|
++num;
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
symlink_native (const char *oldpath, path_conv &win32_newpath)
|
symlink_native (const char *oldpath, path_conv &win32_newpath)
|
||||||
{
|
{
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
path_conv win32_oldpath;
|
path_conv win32_oldpath;
|
||||||
PUNICODE_STRING final_oldpath, final_newpath;
|
PUNICODE_STRING final_oldpath, final_newpath;
|
||||||
|
UNICODE_STRING final_oldpath_buf;
|
||||||
|
|
||||||
if (isabspath (oldpath))
|
if (isabspath (oldpath))
|
||||||
{
|
{
|
||||||
@ -1554,10 +1567,48 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
|
|||||||
stpcpy (stpncpy (absoldpath, win32_newpath.normalized_path, len),
|
stpcpy (stpncpy (absoldpath, win32_newpath.normalized_path, len),
|
||||||
oldpath);
|
oldpath);
|
||||||
win32_oldpath.check (absoldpath, PC_SYM_NOFOLLOW, stat_suffixes);
|
win32_oldpath.check (absoldpath, PC_SYM_NOFOLLOW, stat_suffixes);
|
||||||
UNICODE_STRING dirpath;
|
|
||||||
RtlSplitUnicodePath (win32_newpath.get_nt_native_path (), &dirpath, NULL);
|
/* Try hard to keep Windows symlink path relative. */
|
||||||
|
|
||||||
|
/* 1. Find common path prefix. */
|
||||||
|
PWCHAR c_old = win32_oldpath.get_nt_native_path ()->Buffer;
|
||||||
|
PWCHAR c_new = win32_newpath.get_nt_native_path ()->Buffer;
|
||||||
|
/* Windows compatible == always check case insensitive. */
|
||||||
|
while (towupper (*c_old++) == towupper (*c_new++))
|
||||||
|
;
|
||||||
|
/* The last component could share a common prefix, so make sure we end
|
||||||
|
up on the first char after the last common backslash. */
|
||||||
|
while (c_old[-1] != L'\\')
|
||||||
|
--c_old, --c_new;
|
||||||
|
|
||||||
|
/* 2. Check if prefix is long enough. The prefix must at least points to
|
||||||
|
a complete device: \\?\X:\ or \\?\UNC\server\share\ are the minimum
|
||||||
|
prefix strings. We start counting behind the \\?\ for speed. */
|
||||||
|
int num = cnt_bs (win32_oldpath.get_nt_native_path ()->Buffer + 4, c_old);
|
||||||
|
if (num < 1 /* locale drive. */
|
||||||
|
|| (win32_oldpath.get_nt_native_path ()->Buffer[6] != L':'
|
||||||
|
&& num < 3)) /* UNC path. */
|
||||||
|
{
|
||||||
|
/* 3a. No valid common path prefix: Create absolute symlink. */
|
||||||
final_oldpath = win32_oldpath.get_nt_native_path ();
|
final_oldpath = win32_oldpath.get_nt_native_path ();
|
||||||
final_oldpath->Buffer += dirpath.Length / sizeof (WCHAR);
|
final_oldpath->Buffer[1] = L'\\';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* 3b. Common path prefx. Count number of additional directories
|
||||||
|
in symlink's path, and prepend as much ".." path components
|
||||||
|
to the target path. */
|
||||||
|
PWCHAR e_new = win32_newpath.get_nt_native_path ()->Buffer
|
||||||
|
+ win32_newpath.get_nt_native_path ()->Length
|
||||||
|
/ sizeof (WCHAR);
|
||||||
|
num = cnt_bs (c_new, e_new);
|
||||||
|
final_oldpath = &final_oldpath_buf;
|
||||||
|
final_oldpath->Buffer = tp.w_get ();
|
||||||
|
PWCHAR e_old = final_oldpath->Buffer;
|
||||||
|
while (num-- > 0)
|
||||||
|
e_old = wcpcpy (e_old, L"..\\");
|
||||||
|
wcpcpy (e_old, c_old);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* If the symlink target doesn't exist, don't create native symlink.
|
/* If the symlink target doesn't exist, don't create native symlink.
|
||||||
Otherwise the directory flag in the symlink is potentially wrong
|
Otherwise the directory flag in the symlink is potentially wrong
|
||||||
|
@ -11,3 +11,6 @@ Bug fixes:
|
|||||||
|
|
||||||
- Fix EFAULT when reading large clipboard.
|
- Fix EFAULT when reading large clipboard.
|
||||||
Fixes: http://cygwin.com/ml/cygwin/2013-06/msg00311.html
|
Fixes: http://cygwin.com/ml/cygwin/2013-06/msg00311.html
|
||||||
|
|
||||||
|
- Fix creation of relative native symlinks.
|
||||||
|
Fixes: http://cygwin.com/ml/cygwin/2013-06/msg00340.html
|
||||||
|
Loading…
x
Reference in New Issue
Block a user