summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/path.cc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2009-08-26 20:32:35 +0000
committerCorinna Vinschen <corinna@vinschen.de>2009-08-26 20:32:35 +0000
commit2671595b4acd429d9f9e8f52c5da6f71e1a0762f (patch)
tree187c1c57fad38583d86ef87c34270b2c3ba6c55e /winsup/cygwin/path.cc
parent50bd7b0bb6e66425b5b1cb315dacd157a6d30e1c (diff)
downloadcygnal-2671595b4acd429d9f9e8f52c5da6f71e1a0762f.tar.gz
cygnal-2671595b4acd429d9f9e8f52c5da6f71e1a0762f.tar.bz2
cygnal-2671595b4acd429d9f9e8f52c5da6f71e1a0762f.zip
* path.h (INTERIX_SYMLINK_COOKIE): Define.
* path.cc (symlink_info::check_sysfile): Read Interix symlinks as well.
Diffstat (limited to 'winsup/cygwin/path.cc')
-rw-r--r--winsup/cygwin/path.cc36
1 files changed, 30 insertions, 6 deletions
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 4d0b1b9d2..db514d325 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -1784,6 +1784,7 @@ symlink_info::check_sysfile (HANDLE in_h)
NTSTATUS status;
HANDLE h;
IO_STATUS_BLOCK io;
+ bool interix_symlink = false;
InitializeObjectAttributes (&attr, &same, 0, in_h, NULL);
status = NtOpenFile (&h, FILE_READ_DATA | SYNCHRONIZE,
@@ -1805,7 +1806,26 @@ symlink_info::check_sysfile (HANDLE in_h)
{
/* It's a symlink. */
pflags = PATH_SYMLINK;
-
+ }
+ else if (io.Information == sizeof (cookie_buf)
+ && memcmp (cookie_buf, SOCKET_COOKIE, sizeof (cookie_buf)) == 0)
+ pflags |= PATH_SOCKET;
+ else if (io.Information >= sizeof (INTERIX_SYMLINK_COOKIE)
+ && memcmp (cookie_buf, INTERIX_SYMLINK_COOKIE,
+ sizeof (INTERIX_SYMLINK_COOKIE) - 1) == 0)
+ {
+ /* It's an Interix symlink. */
+ pflags = PATH_SYMLINK;
+ interix_symlink = true;
+ /* Interix symlink cookies are shorter than Cygwin symlink cookies, so
+ in case of an Interix symlink cooky we have read too far into the
+ file. Set file pointer back to the position right after the cookie. */
+ FILE_POSITION_INFORMATION fpi;
+ fpi.CurrentByteOffset.QuadPart = sizeof (INTERIX_SYMLINK_COOKIE) - 1;
+ NtSetInformationFile (h, &io, &fpi, sizeof fpi, FilePositionInformation);
+ }
+ if (pflags == PATH_SYMLINK)
+ {
status = NtReadFile (h, NULL, NULL, NULL, &io, srcbuf,
NT_MAX_PATH, NULL, NULL);
if (!NT_SUCCESS (status))
@@ -1814,10 +1834,17 @@ symlink_info::check_sysfile (HANDLE in_h)
if (status != STATUS_END_OF_FILE)
set_error (EIO);
}
- else if (*(PWCHAR) srcbuf == 0xfeff) /* BOM */
+ else if (*(PWCHAR) srcbuf == 0xfeff /* BOM */
+ || interix_symlink)
{
+ /* Add trailing 0 to Interix symlink target. Skip BOM in Cygwin
+ symlinks. */
+ if (interix_symlink)
+ ((PWCHAR) srcbuf)[io.Information / sizeof (WCHAR)] = L'\0';
+ else
+ srcbuf += 2;
char *tmpbuf = tp.c_get ();
- if (sys_wcstombs (tmpbuf, NT_MAX_PATH, (PWCHAR) (srcbuf + 2))
+ if (sys_wcstombs (tmpbuf, NT_MAX_PATH, (PWCHAR) srcbuf)
> SYMLINK_MAX + 1)
debug_printf ("symlink string too long");
else
@@ -1828,9 +1855,6 @@ symlink_info::check_sysfile (HANDLE in_h)
else
res = posixify (srcbuf);
}
- else if (io.Information == sizeof (cookie_buf)
- && memcmp (cookie_buf, SOCKET_COOKIE, sizeof (cookie_buf)) == 0)
- pflags |= PATH_SOCKET;
NtClose (h);
return res;
}