summaryrefslogtreecommitdiffstats
path: root/Source/kwsys/SystemTools.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2019-01-24 14:52:25 (GMT)
committerBrad King <brad.king@kitware.com>2019-01-24 14:52:25 (GMT)
commitd67ce0a61e6a4c8b639cb19f575b4f0a5b2d033f (patch)
treebbc71ae1f140a3f99bd7398829c5d9ee3f1d410c /Source/kwsys/SystemTools.cxx
parent1d02491950b0aa05d2053e7fa32b39dca31e537b (diff)
parentbee32e96b392ff4e0f2baf8fdc831a9e5240c7d9 (diff)
downloadCMake-d67ce0a61e6a4c8b639cb19f575b4f0a5b2d033f.zip
CMake-d67ce0a61e6a4c8b639cb19f575b4f0a5b2d033f.tar.gz
CMake-d67ce0a61e6a4c8b639cb19f575b4f0a5b2d033f.tar.bz2
Merge branch 'upstream-KWSys' into update-kwsys
* upstream-KWSys: KWSys 2019-01-24 (b9dd1636)
Diffstat (limited to 'Source/kwsys/SystemTools.cxx')
-rw-r--r--Source/kwsys/SystemTools.cxx58
1 files changed, 55 insertions, 3 deletions
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index c5160a9..cbdfe11 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -2161,6 +2161,32 @@ bool SystemTools::FilesDiffer(const std::string& source,
return false;
}
+bool SystemTools::TextFilesDiffer(const std::string& path1,
+ const std::string& path2)
+{
+ kwsys::ifstream if1(path1.c_str());
+ kwsys::ifstream if2(path2.c_str());
+ if (!if1 || !if2) {
+ return true;
+ }
+
+ for (;;) {
+ std::string line1, line2;
+ bool hasData1 = GetLineFromStream(if1, line1);
+ bool hasData2 = GetLineFromStream(if2, line2);
+ if (hasData1 != hasData2) {
+ return true;
+ }
+ if (!hasData1) {
+ break;
+ }
+ if (line1 != line2) {
+ return true;
+ }
+ }
+ return false;
+}
+
/**
* Blockwise copy source to destination file
*/
@@ -2979,10 +3005,36 @@ bool SystemTools::FileIsDirectory(const std::string& inName)
bool SystemTools::FileIsSymlink(const std::string& name)
{
#if defined(_WIN32)
- DWORD attr =
- GetFileAttributesW(Encoding::ToWindowsExtendedPath(name).c_str());
+ std::wstring path = Encoding::ToWindowsExtendedPath(name);
+ DWORD attr = GetFileAttributesW(path.c_str());
if (attr != INVALID_FILE_ATTRIBUTES) {
- return (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
+ if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
+ // FILE_ATTRIBUTE_REPARSE_POINT means:
+ // * a file or directory that has an associated reparse point, or
+ // * a file that is a symbolic link.
+ HANDLE hFile = CreateFileW(
+ path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ return false;
+ }
+ byte buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
+ DWORD bytesReturned = 0;
+ if (!DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, buffer,
+ MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytesReturned,
+ NULL)) {
+ CloseHandle(hFile);
+ // Since FILE_ATTRIBUTE_REPARSE_POINT is set this file must be
+ // a symbolic link if it is not a reparse point.
+ return GetLastError() == ERROR_NOT_A_REPARSE_POINT;
+ }
+ CloseHandle(hFile);
+ ULONG reparseTag =
+ reinterpret_cast<PREPARSE_GUID_DATA_BUFFER>(&buffer[0])->ReparseTag;
+ return (reparseTag == IO_REPARSE_TAG_SYMLINK) ||
+ (reparseTag == IO_REPARSE_TAG_MOUNT_POINT);
+ }
+ return false;
} else {
return false;
}