1
0
Эх сурвалжийг харах

KWSys 2016-02-22 (4847aedd)

Code extracted from:

    http://public.kitware.com/KWSys.git

at commit 4847aedde22b0026accbb71e5480ed353a330e02 (master).

Upstream Shortlog
-----------------

Ben Boeckel (1):
      de83c4d4 SystemTools: support deleting junction points

Chuck Atkins (1):
      3e1b7395 SystemInformation: Ignore buffers and cache when reporting host memory use

Costy Petrisor (1):
      9fe15333 Update hidden includes to support CMake header dependency scanning

Zack Galbreath (1):
      4847aedd Process: Allow timeout to be changed after child starts
KWSys Upstream 9 жил өмнө
parent
commit
a132064b48

+ 1 - 0
CommandLineArguments.cxx

@@ -20,6 +20,7 @@
 #if 0
 # include "CommandLineArguments.hxx.in"
 # include "Configure.hxx.in"
+# include "String.hxx.in"
 #endif
 
 #include <vector>

+ 2 - 0
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;
 }
 
 /*--------------------------------------------------------------------------*/

+ 3 - 1
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;
 }
 
 /*--------------------------------------------------------------------------*/

+ 25 - 15
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

+ 107 - 0
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)

+ 0 - 1
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>

+ 6 - 0
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;