summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2016-02-22 09:03:40 -0500
committerBrad King <brad.king@kitware.com>2016-02-22 09:03:40 -0500
commitd010ba9fa71035f44e6df2fdf86bf38ab8559df5 (patch)
tree5febe614b72558ce1a618d15fc67f141203049f4 /Source
parentdf246f7c7f655f9ea6df0c64e131d2eb0cafd789 (diff)
parenta132064b4821ee21c45717b459351ac4ffe4d372 (diff)
downloadcmake-d010ba9fa71035f44e6df2fdf86bf38ab8559df5.tar.gz
Merge branch 'upstream-KWSys' into update-kwsys
* upstream-KWSys: KWSys 2016-02-22 (4847aedd)
Diffstat (limited to 'Source')
-rw-r--r--Source/kwsys/CommandLineArguments.cxx1
-rw-r--r--Source/kwsys/ProcessUNIX.c2
-rw-r--r--Source/kwsys/ProcessWin32.c4
-rw-r--r--Source/kwsys/SystemInformation.cxx40
-rw-r--r--Source/kwsys/SystemTools.cxx107
-rw-r--r--Source/kwsys/testHashSTL.cxx1
-rw-r--r--Source/kwsys/testIOS.cxx6
7 files changed, 144 insertions, 17 deletions
diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx
index 36368368bf..f713294da0 100644
--- a/Source/kwsys/CommandLineArguments.cxx
+++ b/Source/kwsys/CommandLineArguments.cxx
@@ -20,6 +20,7 @@
#if 0
# include "CommandLineArguments.hxx.in"
# include "Configure.hxx.in"
+# include "String.hxx.in"
#endif
#include <vector>
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index 07c644b8ef..74029553b6 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -505,6 +505,8 @@ void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout)
{
cp->Timeout = 0;
}
+ // Force recomputation of TimeoutTime.
+ cp->TimeoutTime.tv_sec = -1;
}
/*--------------------------------------------------------------------------*/
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index 1f8749fbea..a18ea2748f 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -17,7 +17,7 @@
duplicate the above list of headers. */
#if 0
# include "Process.h.in"
-# include "Encoding_c.h.in"
+# include "Encoding.h.in"
#endif
/*
@@ -698,6 +698,8 @@ void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout)
{
cp->Timeout = 0;
}
+ // Force recomputation of TimeoutTime.
+ cp->TimeoutTime.QuadPart = -1;
}
/*--------------------------------------------------------------------------*/
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index cddcc8dcb6..127a048226 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -43,7 +43,6 @@
#if 0
# include "SystemInformation.hxx.in"
# include "Process.h.in"
-# include "Configure.hxx.in"
#endif
#include <iostream>
@@ -3570,33 +3569,44 @@ SystemInformationImplementation::GetHostMemoryUsed()
return (statex.ullTotalPhys - statex.ullAvailPhys)/1024;
# endif
#elif defined(__linux)
- const char *names[3]={"MemTotal:","MemFree:",NULL};
- SystemInformation::LongLong values[2]={SystemInformation::LongLong(0)};
- int ierr=GetFieldsFromFile("/proc/meminfo",names,values);
+ // First try to use MemAvailable, but it only works on newer kernels
+ const char *names2[3]={"MemTotal:","MemAvailable:",NULL};
+ SystemInformation::LongLong values2[2]={SystemInformation::LongLong(0)};
+ int ierr=GetFieldsFromFile("/proc/meminfo",names2,values2);
if (ierr)
{
- return ierr;
- }
- SystemInformation::LongLong &memTotal=values[0];
- SystemInformation::LongLong &memFree=values[1];
- return memTotal - memFree;
+ const char *names4[5]={"MemTotal:","MemFree:","Buffers:","Cached:",NULL};
+ SystemInformation::LongLong values4[4]={SystemInformation::LongLong(0)};
+ ierr=GetFieldsFromFile("/proc/meminfo",names4,values4);
+ if(ierr)
+ {
+ return ierr;
+ }
+ SystemInformation::LongLong &memTotal=values4[0];
+ SystemInformation::LongLong &memFree=values4[1];
+ SystemInformation::LongLong &memBuffers=values4[2];
+ SystemInformation::LongLong &memCached=values4[3];
+ return memTotal - memFree - memBuffers - memCached;
+ }
+ SystemInformation::LongLong &memTotal=values2[0];
+ SystemInformation::LongLong &memAvail=values2[1];
+ return memTotal - memAvail;
#elif defined(__APPLE__)
SystemInformation::LongLong psz=getpagesize();
if (psz<1)
{
return -1;
}
- const char *names[4]={"Pages active:","Pages inactive:","Pages wired down:",NULL};
- SystemInformation::LongLong values[3]={SystemInformation::LongLong(0)};
+ const char *names[3]={"Pages wired down:","Pages active:",NULL};
+ SystemInformation::LongLong values[2]={SystemInformation::LongLong(0)};
int ierr=GetFieldsFromCommand("vm_stat", names, values);
if (ierr)
{
return -1;
}
- SystemInformation::LongLong &vmActive=values[0];
- SystemInformation::LongLong &vmInactive=values[1];
- SystemInformation::LongLong &vmWired=values[2];
- return ((vmActive+vmInactive+vmWired)*psz)/1024;
+ SystemInformation::LongLong &vmWired=values[0];
+ SystemInformation::LongLong &vmActive=values[1];
+ return ((vmActive+vmWired)*psz)/1024;
#else
return 0;
#endif
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index e3428f8783..544a638cab 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -35,10 +35,12 @@
#include <fstream>
#include <sstream>
#include <set>
+#include <vector>
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
#if 0
+# include "RegularExpression.hxx.in"
# include "SystemTools.hxx.in"
# include "Directory.hxx.in"
# include "FStream.hxx.in"
@@ -87,6 +89,7 @@
// Windows API.
#if defined(_WIN32)
# include <windows.h>
+# include <winioctl.h>
# ifndef INVALID_FILE_ATTRIBUTES
# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
# endif
@@ -2754,6 +2757,106 @@ std::string SystemTools::GetLastSystemError()
return strerror(e);
}
+#ifdef _WIN32
+
+static bool IsJunction(const std::wstring& source)
+{
+#ifdef FSCTL_GET_REPARSE_POINT
+ const DWORD JUNCTION_ATTRS = FILE_ATTRIBUTE_DIRECTORY |
+ FILE_ATTRIBUTE_REPARSE_POINT;
+ DWORD attrs = GetFileAttributesW(source.c_str());
+ if (attrs == INVALID_FILE_ATTRIBUTES)
+ {
+ return false;
+ }
+ if ((attrs & JUNCTION_ATTRS) != JUNCTION_ATTRS)
+ {
+ return false;
+ }
+
+ // Adjust privileges so that we can succefully open junction points.
+ HANDLE token;
+ TOKEN_PRIVILEGES privs;
+ OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token);
+ LookupPrivilegeValue(NULL, SE_BACKUP_NAME, &privs.Privileges[0].Luid);
+ privs.PrivilegeCount = 1;
+ privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+ AdjustTokenPrivileges(token, FALSE, &privs, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
+ CloseHandle(token);
+
+ HANDLE dir = CreateFileW(source.c_str(), GENERIC_READ,
+ 0, NULL, OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (dir == INVALID_HANDLE_VALUE)
+ {
+ return false;
+ }
+
+ // Query whether this is a reparse point or not.
+ BYTE buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
+ REPARSE_GUID_DATA_BUFFER *reparse_buffer =
+ (REPARSE_GUID_DATA_BUFFER*) buffer;
+ DWORD sentinel;
+
+ BOOL success = DeviceIoControl(
+ dir, FSCTL_GET_REPARSE_POINT,
+ NULL, 0,
+ reparse_buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE,
+ &sentinel, NULL);
+
+ CloseHandle(dir);
+
+ return (success && (reparse_buffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT));
+#else
+ return false;
+#endif
+}
+
+static bool DeleteJunction(const std::wstring& source)
+{
+#ifdef FSCTL_DELETE_REPARSE_POINT
+ // Adjust privileges so that we can succefully open junction points as
+ // read/write.
+ HANDLE token;
+ TOKEN_PRIVILEGES privs;
+ OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token);
+ LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &privs.Privileges[0].Luid);
+ privs.PrivilegeCount = 1;
+ privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+ AdjustTokenPrivileges(token, FALSE, &privs, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
+ CloseHandle(token);
+
+ HANDLE dir = CreateFileW(source.c_str(), GENERIC_READ | GENERIC_WRITE,
+ 0, NULL, OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (dir == INVALID_HANDLE_VALUE)
+ {
+ return false;
+ }
+
+ // Set up the structure so that we can delete the junction.
+ std::vector<BYTE> buffer(REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, 0);
+ REPARSE_GUID_DATA_BUFFER *reparse_buffer =
+ (REPARSE_GUID_DATA_BUFFER*) &buffer[0];
+ DWORD sentinel;
+
+ reparse_buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
+
+ BOOL success = DeviceIoControl(
+ dir, FSCTL_DELETE_REPARSE_POINT,
+ reparse_buffer, REPARSE_GUID_DATA_BUFFER_HEADER_SIZE,
+ NULL, 0,
+ &sentinel, NULL);
+
+ CloseHandle(dir);
+
+ return !!success;
+#else
+ return false;
+#endif
+}
+#endif
+
bool SystemTools::RemoveFile(const std::string& source)
{
#ifdef _WIN32
@@ -2781,6 +2884,10 @@ bool SystemTools::RemoveFile(const std::string& source)
SetLastError(err);
return false;
}
+ if (IsJunction(ws) && !DeleteJunction(ws))
+ {
+ return false;
+ }
if (DeleteFileW(ws.c_str()) ||
GetLastError() == ERROR_FILE_NOT_FOUND ||
GetLastError() == ERROR_PATH_NOT_FOUND)
diff --git a/Source/kwsys/testHashSTL.cxx b/Source/kwsys/testHashSTL.cxx
index ab1f83e780..ae66cebead 100644
--- a/Source/kwsys/testHashSTL.cxx
+++ b/Source/kwsys/testHashSTL.cxx
@@ -18,7 +18,6 @@
#if 0
# include "hash_map.hxx.in"
# include "hash_set.hxx.in"
-# include "hashtable.hxx.in"
#endif
#include <iostream>
diff --git a/Source/kwsys/testIOS.cxx b/Source/kwsys/testIOS.cxx
index 396a09d47d..5ff7955bfa 100644
--- a/Source/kwsys/testIOS.cxx
+++ b/Source/kwsys/testIOS.cxx
@@ -18,6 +18,12 @@
#include <vector>
#include <string.h> /* strlen */
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# include "Configure.hxx.in"
+#endif
+
int testIOS(int, char*[])
{
std::ostringstream ostr;