summaryrefslogtreecommitdiffstats
path: root/Source/kwsys
diff options
context:
space:
mode:
Diffstat (limited to 'Source/kwsys')
-rw-r--r--Source/kwsys/.gitattributes17
-rw-r--r--Source/kwsys/CMakeLists.txt21
-rw-r--r--Source/kwsys/ConsoleBuf.hxx.in3
-rw-r--r--Source/kwsys/Encoding.hxx.in13
-rw-r--r--Source/kwsys/EncodingCXX.cxx58
-rw-r--r--Source/kwsys/FStream.hxx.in10
-rw-r--r--Source/kwsys/SystemInformation.cxx281
-rw-r--r--Source/kwsys/SystemInformation.hxx.in3
-rw-r--r--Source/kwsys/SystemTools.cxx193
-rw-r--r--Source/kwsys/SystemTools.hxx.in37
-rw-r--r--Source/kwsys/testEncoding.cxx83
-rw-r--r--Source/kwsys/testSystemInformation.cxx2
-rw-r--r--Source/kwsys/testSystemTools.cxx92
13 files changed, 425 insertions, 388 deletions
diff --git a/Source/kwsys/.gitattributes b/Source/kwsys/.gitattributes
index a121ad1..7065eb5 100644
--- a/Source/kwsys/.gitattributes
+++ b/Source/kwsys/.gitattributes
@@ -1,12 +1,13 @@
.git* export-ignore
-*.c whitespace=tab-in-indent,no-lf-at-eof
-*.h whitespace=tab-in-indent,no-lf-at-eof
-*.h.in whitespace=tab-in-indent,no-lf-at-eof
-*.cxx whitespace=tab-in-indent,no-lf-at-eof
-*.hxx whitespace=tab-in-indent,no-lf-at-eof
-*.hxx.in whitespace=tab-in-indent,no-lf-at-eof
-*.txt whitespace=tab-in-indent,no-lf-at-eof
-*.cmake whitespace=tab-in-indent,no-lf-at-eof
+*.c kwsys-c-style
+*.c.in kwsys-c-style
+*.cxx kwsys-c-style
+*.h kwsys-c-style
+*.h.in kwsys-c-style
+*.hxx kwsys-c-style
+*.hxx.in kwsys-c-style
+*.cmake whitespace=tab-in-indent
*.rst whitespace=tab-in-indent conflict-marker-size=79
+*.txt whitespace=tab-in-indent
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index d4fe8a7..e915b1a 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -69,6 +69,7 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR)
FOREACH(p
CMP0025 # CMake 3.0, Compiler id for Apple Clang is now AppleClang.
+ CMP0048 # CMake 3.0, Let the project command manage version variables.
CMP0056 # CMake 3.2, Honor link flags in try_compile() source-file signature.
CMP0063 # CMake 3.3, Honor visibility properties for all target types.
)
@@ -796,6 +797,10 @@ ENDFOREACH()
IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
ADD_LIBRARY(${KWSYS_NAMESPACE} ${KWSYS_LIBRARY_TYPE}
${KWSYS_C_SRCS} ${KWSYS_CXX_SRCS})
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE} PROPERTY C_CLANG_TIDY "")
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE} PROPERTY CXX_CLANG_TIDY "")
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE} PROPERTY C_INCLUDE_WHAT_YOU_USE "")
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE} PROPERTY CXX_INCLUDE_WHAT_YOU_USE "")
SET_PROPERTY(TARGET ${KWSYS_NAMESPACE} PROPERTY LABELS ${KWSYS_LABELS_LIB})
IF(KWSYS_USE_DynamicLoader)
IF(UNIX)
@@ -940,13 +945,17 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
ENDIF()
IF(KWSYS_USE_ConsoleBuf)
ADD_EXECUTABLE(testConsoleBufChild testConsoleBufChild.cxx)
+ SET_PROPERTY(TARGET testConsoleBufChild PROPERTY C_CLANG_TIDY "")
+ SET_PROPERTY(TARGET testConsoleBufChild PROPERTY CXX_CLANG_TIDY "")
+ SET_PROPERTY(TARGET testConsoleBufChild PROPERTY C_INCLUDE_WHAT_YOU_USE "")
+ SET_PROPERTY(TARGET testConsoleBufChild PROPERTY CXX_INCLUDE_WHAT_YOU_USE "")
SET_PROPERTY(TARGET testConsoleBufChild PROPERTY LABELS ${KWSYS_LABELS_EXE})
TARGET_LINK_LIBRARIES(testConsoleBufChild ${KWSYS_NAMESPACE})
SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
testConsoleBuf
)
IF("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" AND
- NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.0")
+ CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "19.0.23506")
set_property(SOURCE testConsoleBuf.cxx testConsoleBufChild.cxx PROPERTY COMPILE_FLAGS /utf-8)
ENDIF()
SET_PROPERTY(SOURCE testConsoleBuf.cxx APPEND PROPERTY COMPILE_DEFINITIONS
@@ -967,6 +976,10 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
${KWSYS_CXX_TESTS}
)
ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_CXX_TEST_SRCS})
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY C_CLANG_TIDY "")
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY CXX_CLANG_TIDY "")
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY C_INCLUDE_WHAT_YOU_USE "")
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY CXX_INCLUDE_WHAT_YOU_USE "")
SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY LABELS ${KWSYS_LABELS_EXE})
TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_NAMESPACE})
@@ -1032,8 +1045,12 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
# Some Apple compilers produce bad optimizations in this source.
IF(APPLE AND CMAKE_C_COMPILER_ID MATCHES "^(GNU|LLVM)$")
SET_SOURCE_FILES_PROPERTIES(testProcess.c PROPERTIES COMPILE_FLAGS -O0)
- ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "XL")
+ ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "XL" AND
+ NOT (CMAKE_SYSTEM MATCHES "Linux.*ppc64le" AND
+ NOT CMAKE_C_COMPILER_VERSION VERSION_LESS "13.1.1"))
# Tell IBM XL not to warn about our test infinite loop
+ # v13.1.1 and newer on Linux ppc64le is clang based and does not accept
+ # the -qsuppress option
SET_PROPERTY(SOURCE testProcess.c PROPERTY COMPILE_FLAGS -qsuppress=1500-010)
ENDIF()
diff --git a/Source/kwsys/ConsoleBuf.hxx.in b/Source/kwsys/ConsoleBuf.hxx.in
index cb58865..32e680c 100644
--- a/Source/kwsys/ConsoleBuf.hxx.in
+++ b/Source/kwsys/ConsoleBuf.hxx.in
@@ -25,8 +25,7 @@ namespace @KWSYS_NAMESPACE@ {
#if defined(_WIN32)
template <class CharT, class Traits = std::char_traits<CharT> >
-class @KWSYS_NAMESPACE@_EXPORT BasicConsoleBuf
- : public std::basic_streambuf<CharT, Traits>
+class BasicConsoleBuf : public std::basic_streambuf<CharT, Traits>
{
public:
typedef typename Traits::int_type int_type;
diff --git a/Source/kwsys/Encoding.hxx.in b/Source/kwsys/Encoding.hxx.in
index 6639efd..09691fd 100644
--- a/Source/kwsys/Encoding.hxx.in
+++ b/Source/kwsys/Encoding.hxx.in
@@ -13,7 +13,7 @@ class @KWSYS_NAMESPACE@_EXPORT Encoding
{
public:
// Container class for argc/argv.
- class CommandLineArguments
+ class @KWSYS_NAMESPACE@_EXPORT CommandLineArguments
{
public:
// On Windows, get the program command line arguments
@@ -59,6 +59,17 @@ public:
static std::string ToNarrow(const std::wstring& str);
static std::string ToNarrow(const wchar_t* str);
+#if defined(_WIN32)
+ /**
+ * Convert the path to an extended length path to avoid MAX_PATH length
+ * limitations on Windows. If the input is a local path the result will be
+ * prefixed with \\?\; if the input is instead a network path, the result
+ * will be prefixed with \\?\UNC\. All output will also be converted to
+ * absolute paths with Windows-style backslashes.
+ **/
+ static std::wstring ToWindowsExtendedPath(std::string const&);
+#endif
+
#endif // @KWSYS_NAMESPACE@_STL_HAS_WSTRING
}; // class Encoding
diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx
index e904c1a..641c0e6 100644
--- a/Source/kwsys/EncodingCXX.cxx
+++ b/Source/kwsys/EncodingCXX.cxx
@@ -29,6 +29,7 @@
#if defined(_WIN32)
#include <windows.h>
+#include <ctype.h>
#include <shellapi.h>
#endif
@@ -214,6 +215,63 @@ std::string Encoding::ToNarrow(const wchar_t* wcstr)
}
return str;
}
+
+#if defined(_WIN32)
+// Convert local paths to UNC style paths
+std::wstring Encoding::ToWindowsExtendedPath(std::string const& source)
+{
+ std::wstring wsource = Encoding::ToWide(source);
+
+ // Resolve any relative paths
+ DWORD wfull_len;
+
+ /* The +3 is a workaround for a bug in some versions of GetFullPathNameW that
+ * won't return a large enough buffer size if the input is too small */
+ wfull_len = GetFullPathNameW(wsource.c_str(), 0, NULL, NULL) + 3;
+ std::vector<wchar_t> wfull(wfull_len);
+ GetFullPathNameW(wsource.c_str(), wfull_len, &wfull[0], NULL);
+
+ /* This should get the correct size without any extra padding from the
+ * previous size workaround. */
+ wfull_len = static_cast<DWORD>(wcslen(&wfull[0]));
+
+ if (wfull_len >= 2 && isalpha(wfull[0]) &&
+ wfull[1] == L':') { /* C:\Foo\bar\FooBar.txt */
+ return L"\\\\?\\" + std::wstring(&wfull[0]);
+ } else if (wfull_len >= 2 && wfull[0] == L'\\' &&
+ wfull[1] == L'\\') { /* Starts with \\ */
+ if (wfull_len >= 4 && wfull[2] == L'?' &&
+ wfull[3] == L'\\') { /* Starts with \\?\ */
+ if (wfull_len >= 8 && wfull[4] == L'U' && wfull[5] == L'N' &&
+ wfull[6] == L'C' &&
+ wfull[7] == L'\\') { /* \\?\UNC\Foo\bar\FooBar.txt */
+ return std::wstring(&wfull[0]);
+ } else if (wfull_len >= 6 && isalpha(wfull[4]) &&
+ wfull[5] == L':') { /* \\?\C:\Foo\bar\FooBar.txt */
+ return std::wstring(&wfull[0]);
+ } else if (wfull_len >= 5) { /* \\?\Foo\bar\FooBar.txt */
+ return L"\\\\?\\UNC\\" + std::wstring(&wfull[4]);
+ }
+ } else if (wfull_len >= 4 && wfull[2] == L'.' &&
+ wfull[3] == L'\\') { /* Starts with \\.\ a device name */
+ if (wfull_len >= 6 && isalpha(wfull[4]) &&
+ wfull[5] == L':') { /* \\.\C:\Foo\bar\FooBar.txt */
+ return L"\\\\?\\" + std::wstring(&wfull[4]);
+ } else if (wfull_len >=
+ 5) { /* \\.\Foo\bar\ Device name is left unchanged */
+ return std::wstring(&wfull[0]);
+ }
+ } else if (wfull_len >= 3) { /* \\Foo\bar\FooBar.txt */
+ return L"\\\\?\\UNC\\" + std::wstring(&wfull[2]);
+ }
+ }
+
+ // If this case has been reached, then the path is invalid. Leave it
+ // unchanged
+ return Encoding::ToWide(source);
+}
+#endif
+
#endif // KWSYS_STL_HAS_WSTRING
} // namespace KWSYS_NAMESPACE
diff --git a/Source/kwsys/FStream.hxx.in b/Source/kwsys/FStream.hxx.in
index 736214f..a4c65fe 100644
--- a/Source/kwsys/FStream.hxx.in
+++ b/Source/kwsys/FStream.hxx.in
@@ -33,7 +33,7 @@ public:
typedef std::basic_filebuf<CharType, Traits> my_base_type;
basic_filebuf* open(char const* s, std::ios_base::openmode mode)
{
- const std::wstring wstr = Encoding::ToWide(s);
+ const std::wstring wstr = Encoding::ToWindowsExtendedPath(s);
return static_cast<basic_filebuf*>(my_base_type::open(wstr.c_str(), mode));
}
#endif
@@ -93,7 +93,7 @@ public:
#if defined(_MSC_VER)
const bool success = buf_->open(file_name, mode) != 0;
#else
- const std::wstring wstr = Encoding::ToWide(file_name);
+ const std::wstring wstr = Encoding::ToWindowsExtendedPath(file_name);
bool success = false;
std::wstring cmode = getcmode(mode);
file_ = _wfopen(wstr.c_str(), cmode.c_str());
@@ -170,8 +170,6 @@ template <typename CharType, typename Traits = std::char_traits<CharType> >
class basic_ifstream : public std::basic_istream<CharType, Traits>,
public basic_efilebuf<CharType, Traits>
{
- using basic_efilebuf<CharType, Traits>::is_open;
-
public:
typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type
internal_buffer_type;
@@ -201,6 +199,8 @@ public:
void close() { this->_set_state(this->_close(), this, this); }
+ using basic_efilebuf<CharType, Traits>::is_open;
+
internal_buffer_type* rdbuf() const { return this->buf_; }
~basic_ifstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { close(); }
@@ -269,7 +269,7 @@ enum BOM
// If a BOM exists, the stream is advanced to after the BOM.
// This function requires a seekable stream (but not a relative
// seekable stream).
-BOM ReadBOM(std::istream& in);
+@KWSYS_NAMESPACE@_EXPORT BOM ReadBOM(std::istream& in);
}
}
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index e01dcd7..70f1a43 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -35,8 +35,13 @@
#include "SystemInformation.hxx.in"
#endif
+#include <algorithm>
+#include <bitset>
+#include <cassert>
#include <fstream>
#include <iostream>
+#include <limits>
+#include <set>
#include <sstream>
#include <string>
#include <vector>
@@ -394,7 +399,6 @@ public:
bool SupportsMP;
bool HasMMXPlus;
bool HasSSEMMX;
- bool SupportsHyperthreading;
unsigned int LogicalProcessorsPerPhysical;
int APIC_ID;
CPUPowerManagement PowerManagement;
@@ -463,10 +467,9 @@ protected:
unsigned int NumberOfLogicalCPU;
unsigned int NumberOfPhysicalCPU;
- int CPUCount(); // For windows
- unsigned char LogicalCPUPerPhysicalCPU();
+ void CPUCountWindows(); // For windows
unsigned char GetAPICId(); // For windows
- bool IsHyperThreadingSupported();
+ bool IsSMTSupported();
static LongLong GetCyclesDifference(DELAY_FUNC, unsigned int); // For windows
// For Linux and Cygwin, /proc/cpuinfo formats are slightly different
@@ -536,6 +539,7 @@ protected:
std::string OSRelease;
std::string OSVersion;
std::string OSPlatform;
+ bool OSIs64Bit;
};
SystemInformation::SystemInformation()
@@ -1496,6 +1500,7 @@ SystemInformationImplementation::SystemInformationImplementation()
this->OSRelease = "";
this->OSVersion = "";
this->OSPlatform = "";
+ this->OSIs64Bit = (sizeof(void*) == 8);
}
SystemInformationImplementation::~SystemInformationImplementation()
@@ -1542,7 +1547,7 @@ void SystemInformationImplementation::RunCPUCheck()
RetrieveProcessorSerialNumber();
}
- this->CPUCount();
+ this->CPUCountWindows();
#elif defined(__APPLE__)
this->ParseSysCtl();
@@ -2090,16 +2095,10 @@ bool SystemInformationImplementation::RetrieveCPUFeatures()
// Retrieve Intel specific extended features.
if (this->ChipManufacturer == Intel) {
- this->Features.ExtendedFeatures.SupportsHyperthreading =
- ((cpuinfo[3] & 0x10000000) !=
- 0); // Intel specific: Hyperthreading --> Bit 28
- this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical =
- (this->Features.ExtendedFeatures.SupportsHyperthreading)
- ? ((cpuinfo[1] & 0x00FF0000) >> 16)
- : 1;
-
- if ((this->Features.ExtendedFeatures.SupportsHyperthreading) &&
- (this->Features.HasAPIC)) {
+ bool SupportsSMT =
+ ((cpuinfo[3] & 0x10000000) != 0); // Intel specific: SMT --> Bit 28
+
+ if ((SupportsSMT) && (this->Features.HasAPIC)) {
// Retrieve APIC information if there is one present.
this->Features.ExtendedFeatures.APIC_ID =
((cpuinfo[1] & 0xFF000000) >> 24);
@@ -3401,7 +3400,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
fclose(fd);
buffer.resize(fileSize - 2);
// Number of logical CPUs (combination of multiple processors, multi-core
- // and hyperthreading)
+ // and SMT)
size_t pos = buffer.find("processor\t");
while (pos != buffer.npos) {
this->NumberOfLogicalCPU++;
@@ -3409,30 +3408,25 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
}
#ifdef __linux
- // Find the largest physical id.
- int maxId = -1;
+ // Count sockets.
+ std::set<int> PhysicalIDs;
std::string idc = this->ExtractValueFromCpuInfoFile(buffer, "physical id");
while (this->CurrentPositionInFile != buffer.npos) {
int id = atoi(idc.c_str());
- if (id > maxId) {
- maxId = id;
- }
+ PhysicalIDs.insert(id);
idc = this->ExtractValueFromCpuInfoFile(buffer, "physical id",
this->CurrentPositionInFile + 1);
}
+ uint64_t NumberOfSockets = PhysicalIDs.size();
+ NumberOfSockets = std::max(NumberOfSockets, (uint64_t)1);
// Physical ids returned by Linux don't distinguish cores.
// We want to record the total number of cores in this->NumberOfPhysicalCPU
// (checking only the first proc)
- std::string cores = this->ExtractValueFromCpuInfoFile(buffer, "cpu cores");
- int numberOfCoresPerCPU = atoi(cores.c_str());
- if (maxId > 0) {
- this->NumberOfPhysicalCPU =
- static_cast<unsigned int>(numberOfCoresPerCPU * (maxId + 1));
- } else {
- // Linux Sparc: get cpu count
- this->NumberOfPhysicalCPU =
- atoi(this->ExtractValueFromCpuInfoFile(buffer, "ncpus active").c_str());
- }
+ std::string Cores = this->ExtractValueFromCpuInfoFile(buffer, "cpu cores");
+ unsigned int NumberOfCoresPerSocket = (unsigned int)atoi(Cores.c_str());
+ NumberOfCoresPerSocket = std::max(NumberOfCoresPerSocket, 1u);
+ this->NumberOfPhysicalCPU =
+ NumberOfCoresPerSocket * (unsigned int)NumberOfSockets;
#else // __CYGWIN__
// does not have "physical id" entries, neither "cpu cores"
@@ -3447,7 +3441,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
if (this->NumberOfPhysicalCPU <= 0) {
this->NumberOfPhysicalCPU = 1;
}
- // LogicalProcessorsPerPhysical>1 => hyperthreading.
+ // LogicalProcessorsPerPhysical>1 => SMT.
this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical =
this->NumberOfLogicalCPU / this->NumberOfPhysicalCPU;
@@ -4322,68 +4316,10 @@ void SystemInformationImplementation::DelayOverhead(unsigned int uiMS)
(void)uiMS;
}
-/** Return the number of logical CPU per physical CPUs Works only for windows
- */
-unsigned char SystemInformationImplementation::LogicalCPUPerPhysicalCPU(void)
-{
-#ifdef __APPLE__
- size_t len = 4;
- int cores_per_package = 0;
- int err = sysctlbyname("machdep.cpu.cores_per_package", &cores_per_package,
- &len, NULL, 0);
- if (err != 0) {
- return 1; // That name was not found, default to 1
- }
- return static_cast<unsigned char>(cores_per_package);
-#else
- int Regs[4] = { 0, 0, 0, 0 };
-#if USE_CPUID
- if (!this->IsHyperThreadingSupported()) {
- return static_cast<unsigned char>(1); // HT not supported
- }
- call_cpuid(1, Regs);
-#endif
- return static_cast<unsigned char>((Regs[1] & NUM_LOGICAL_BITS) >> 16);
-#endif
-}
-
/** Works only for windows */
-bool SystemInformationImplementation::IsHyperThreadingSupported()
+bool SystemInformationImplementation::IsSMTSupported()
{
- if (this->Features.ExtendedFeatures.SupportsHyperthreading) {
- return true;
- }
-
-#if USE_CPUID
- int Regs[4] = { 0, 0, 0, 0 }, VendorId[4] = { 0, 0, 0, 0 };
- // Get vendor id string
- if (!call_cpuid(0, VendorId)) {
- return false;
- }
- // eax contains family processor type
- // edx has info about the availability of hyper-Threading
- if (!call_cpuid(1, Regs)) {
- return false;
- }
-
- if (((Regs[0] & FAMILY_ID) == PENTIUM4_ID) || (Regs[0] & EXT_FAMILY_ID)) {
- if (VendorId[1] == 0x756e6547) // 'uneG'
- {
- if (VendorId[3] == 0x49656e69) // 'Ieni'
- {
- if (VendorId[2] == 0x6c65746e) // 'letn'
- {
- // Genuine Intel with hyper-Threading technology
- this->Features.ExtendedFeatures.SupportsHyperthreading =
- ((Regs[3] & HT_BIT) != 0);
- return this->Features.ExtendedFeatures.SupportsHyperthreading;
- }
- }
- }
- }
-#endif
-
- return 0; // Not genuine Intel processor
+ return this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical > 1;
}
/** Return the APIC Id. Works only for windows. */
@@ -4392,7 +4328,7 @@ unsigned char SystemInformationImplementation::GetAPICId()
int Regs[4] = { 0, 0, 0, 0 };
#if USE_CPUID
- if (!this->IsHyperThreadingSupported()) {
+ if (!this->IsSMTSupported()) {
return static_cast<unsigned char>(-1); // HT not supported
} // Logical processor = 1
call_cpuid(1, Regs);
@@ -4402,102 +4338,63 @@ unsigned char SystemInformationImplementation::GetAPICId()
}
/** Count the number of CPUs. Works only on windows. */
-int SystemInformationImplementation::CPUCount()
+void SystemInformationImplementation::CPUCountWindows()
{
#if defined(_WIN32)
- unsigned char StatusFlag = 0;
- SYSTEM_INFO info;
-
this->NumberOfPhysicalCPU = 0;
this->NumberOfLogicalCPU = 0;
- info.dwNumberOfProcessors = 0;
- GetSystemInfo(&info);
-
- // Number of physical processors in a non-Intel system
- // or in a 32-bit Intel system with Hyper-Threading technology disabled
- this->NumberOfPhysicalCPU = (unsigned char)info.dwNumberOfProcessors;
-
- if (this->IsHyperThreadingSupported()) {
- unsigned char HT_Enabled = 0;
- this->NumberOfLogicalCPU = this->LogicalCPUPerPhysicalCPU();
- if (this->NumberOfLogicalCPU >=
- 1) // >1 Doesn't mean HT is enabled in the BIOS
- {
- HANDLE hCurrentProcessHandle;
-#ifndef _WIN64
-#define DWORD_PTR DWORD
-#endif
- DWORD_PTR dwProcessAffinity;
- DWORD_PTR dwSystemAffinity;
- DWORD dwAffinityMask;
-
- // Calculate the appropriate shifts and mask based on the
- // number of logical processors.
- unsigned int i = 1;
- unsigned char PHY_ID_MASK = 0xFF;
- // unsigned char PHY_ID_SHIFT = 0;
-
- while (i < this->NumberOfLogicalCPU) {
- i *= 2;
- PHY_ID_MASK <<= 1;
- // PHY_ID_SHIFT++;
- }
-
- hCurrentProcessHandle = GetCurrentProcess();
- GetProcessAffinityMask(hCurrentProcessHandle, &dwProcessAffinity,
- &dwSystemAffinity);
-
- // Check if available process affinity mask is equal to the
- // available system affinity mask
- if (dwProcessAffinity != dwSystemAffinity) {
- StatusFlag = HT_CANNOT_DETECT;
- this->NumberOfPhysicalCPU = (unsigned char)-1;
- return StatusFlag;
- }
- dwAffinityMask = 1;
- while (dwAffinityMask != 0 && dwAffinityMask <= dwProcessAffinity) {
- // Check if this CPU is available
- if (dwAffinityMask & dwProcessAffinity) {
- if (SetProcessAffinityMask(hCurrentProcessHandle, dwAffinityMask)) {
- unsigned char APIC_ID, LOG_ID;
- Sleep(0); // Give OS time to switch CPU
-
- APIC_ID = GetAPICId();
- LOG_ID = APIC_ID & ~PHY_ID_MASK;
+ typedef BOOL(WINAPI * GetLogicalProcessorInformationType)(
+ PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);
+ static GetLogicalProcessorInformationType pGetLogicalProcessorInformation =
+ (GetLogicalProcessorInformationType)GetProcAddress(
+ GetModuleHandleW(L"kernel32"), "GetLogicalProcessorInformation");
+
+ if (!pGetLogicalProcessorInformation) {
+ // Fallback to approximate implementation on ancient Windows versions.
+ SYSTEM_INFO info;
+ ZeroMemory(&info, sizeof(info));
+ GetSystemInfo(&info);
+ this->NumberOfPhysicalCPU =
+ static_cast<unsigned int>(info.dwNumberOfProcessors);
+ this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU;
+ return;
+ }
- if (LOG_ID != 0) {
- HT_Enabled = 1;
- }
- }
- }
- dwAffinityMask = dwAffinityMask << 1;
- }
- // Reset the processor affinity
- SetProcessAffinityMask(hCurrentProcessHandle, dwProcessAffinity);
+ std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> ProcInfo;
+ {
+ DWORD Length = 0;
+ DWORD rc = pGetLogicalProcessorInformation(NULL, &Length);
+ assert(FALSE == rc);
+ (void)rc; // Silence unused variable warning in Borland C++ 5.81
+ assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
+ ProcInfo.resize(Length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
+ rc = pGetLogicalProcessorInformation(&ProcInfo[0], &Length);
+ assert(rc != FALSE);
+ (void)rc; // Silence unused variable warning in Borland C++ 5.81
+ }
+
+ typedef std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION>::iterator
+ pinfoIt_t;
+ for (pinfoIt_t it = ProcInfo.begin(); it != ProcInfo.end(); ++it) {
+ SYSTEM_LOGICAL_PROCESSOR_INFORMATION PInfo = *it;
+ if (PInfo.Relationship != RelationProcessorCore) {
+ continue;
+ }
- if (this->NumberOfLogicalCPU ==
- 1) // Normal P4 : HT is disabled in hardware
- {
- StatusFlag = HT_DISABLED;
- } else {
- if (HT_Enabled) {
- // Total physical processors in a Hyper-Threading enabled system.
- this->NumberOfPhysicalCPU /= (this->NumberOfLogicalCPU);
- StatusFlag = HT_ENABLED;
- } else {
- StatusFlag = HT_SUPPORTED_NOT_ENABLED;
- }
- }
+ std::bitset<std::numeric_limits<ULONG_PTR>::digits> ProcMask(
+ (unsigned long long)PInfo.ProcessorMask);
+ unsigned int count = (unsigned int)ProcMask.count();
+ if (count == 0) { // I think this should never happen, but just to be safe.
+ continue;
}
- } else {
- // Processors do not have Hyper-Threading technology
- StatusFlag = HT_NOT_CAPABLE;
- this->NumberOfLogicalCPU = 1;
+ this->NumberOfPhysicalCPU++;
+ this->NumberOfLogicalCPU += (unsigned int)count;
+ this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = count;
}
- return StatusFlag;
+ this->NumberOfPhysicalCPU = std::max(1u, this->NumberOfPhysicalCPU);
+ this->NumberOfLogicalCPU = std::max(1u, this->NumberOfLogicalCPU);
#else
- return 0;
#endif
}
@@ -4559,8 +4456,14 @@ bool SystemInformationImplementation::ParseSysCtl()
sysctlbyname("hw.physicalcpu", &this->NumberOfPhysicalCPU, &len, NULL, 0);
len = sizeof(this->NumberOfLogicalCPU);
sysctlbyname("hw.logicalcpu", &this->NumberOfLogicalCPU, &len, NULL, 0);
+
+ int cores_per_package = 0;
+ len = sizeof(cores_per_package);
+ err = sysctlbyname("machdep.cpu.cores_per_package", &cores_per_package, &len,
+ NULL, 0);
+ // That name was not found, default to 1
this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical =
- this->LogicalCPUPerPhysicalCPU();
+ err != 0 ? 1 : static_cast<unsigned char>(cores_per_package);
len = sizeof(value);
sysctlbyname("hw.cpufrequency", &value, &len, NULL, 0);
@@ -5436,10 +5339,20 @@ bool SystemInformationImplementation::QueryOSInformation()
this->Hostname = name;
const char* arch = getenv("PROCESSOR_ARCHITECTURE");
+ const char* wow64 = getenv("PROCESSOR_ARCHITEW6432");
if (arch) {
this->OSPlatform = arch;
}
+ if (wow64) {
+ // the PROCESSOR_ARCHITEW6432 is only defined when running 32bit programs
+ // on 64bit OS
+ this->OSIs64Bit = true;
+ } else if (arch) {
+ // all values other than x86 map to 64bit architectures
+ this->OSIs64Bit = (strncmp(arch, "x86", 3) != 0);
+ }
+
#else
struct utsname unameInfo;
@@ -5450,6 +5363,12 @@ bool SystemInformationImplementation::QueryOSInformation()
this->OSRelease = unameInfo.release;
this->OSVersion = unameInfo.version;
this->OSPlatform = unameInfo.machine;
+
+ // This is still insufficient to capture 64bit architecture such
+ // powerpc and possible mips and sparc
+ if (this->OSPlatform.find_first_of("64") != std::string::npos) {
+ this->OSIs64Bit = true;
+ }
}
#ifdef __APPLE__
@@ -5503,6 +5422,6 @@ void SystemInformationImplementation::TrimNewline(std::string& output)
/** Return true if the machine is 64 bits */
bool SystemInformationImplementation::Is64Bits()
{
- return (sizeof(void*) == 8);
+ return this->OSIs64Bit;
}
}
diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in
index 0fc1067..54e7fc1 100644
--- a/Source/kwsys/SystemInformation.hxx.in
+++ b/Source/kwsys/SystemInformation.hxx.in
@@ -65,9 +65,10 @@ public:
// on this system.
std::string GetOSDescription();
+ // returns if the operating system is 64bit or not.
bool Is64Bits();
- unsigned int GetNumberOfLogicalCPU(); // per physical cpu
+ unsigned int GetNumberOfLogicalCPU();
unsigned int GetNumberOfPhysicalCPU();
bool DoesCPUSupportCPUID();
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 97dd4ae..b6da368 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -54,7 +54,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/stat.h>
#include <time.h>
#if defined(_WIN32) && !defined(_MSC_VER) && defined(__GNUC__)
@@ -217,12 +216,12 @@ static time_t windows_filetime_to_posix_time(const FILETIME& ft)
inline int Mkdir(const std::string& dir)
{
return _wmkdir(
- KWSYS_NAMESPACE::SystemTools::ConvertToWindowsExtendedPath(dir).c_str());
+ KWSYS_NAMESPACE::Encoding::ToWindowsExtendedPath(dir).c_str());
}
inline int Rmdir(const std::string& dir)
{
return _wrmdir(
- KWSYS_NAMESPACE::SystemTools::ConvertToWindowsExtendedPath(dir).c_str());
+ KWSYS_NAMESPACE::Encoding::ToWindowsExtendedPath(dir).c_str());
}
inline const char* Getcwd(char* buf, unsigned int len)
{
@@ -746,7 +745,7 @@ const char* SystemTools::GetExecutableExtension()
FILE* SystemTools::Fopen(const std::string& file, const char* mode)
{
#ifdef _WIN32
- return _wfopen(SystemTools::ConvertToWindowsExtendedPath(file).c_str(),
+ return _wfopen(Encoding::ToWindowsExtendedPath(file).c_str(),
Encoding::ToWide(mode).c_str());
#else
return fopen(file.c_str(), mode);
@@ -1160,8 +1159,7 @@ bool SystemTools::PathExists(const std::string& path)
struct stat st;
return lstat(path.c_str(), &st) == 0;
#elif defined(_WIN32)
- return (GetFileAttributesW(
- SystemTools::ConvertToWindowsExtendedPath(path).c_str()) !=
+ return (GetFileAttributesW(Encoding::ToWindowsExtendedPath(path).c_str()) !=
INVALID_FILE_ATTRIBUTES);
#else
struct stat st;
@@ -1192,9 +1190,9 @@ bool SystemTools::FileExists(const std::string& filename)
}
return access(filename.c_str(), R_OK) == 0;
#elif defined(_WIN32)
- return (GetFileAttributesW(
- SystemTools::ConvertToWindowsExtendedPath(filename).c_str()) !=
- INVALID_FILE_ATTRIBUTES);
+ return (
+ GetFileAttributesW(Encoding::ToWindowsExtendedPath(filename).c_str()) !=
+ INVALID_FILE_ATTRIBUTES);
#else
// SCO OpenServer 5.0.7/3.2's command has 711 permission.
#if defined(_SCO_DS)
@@ -1250,7 +1248,7 @@ bool SystemTools::TestFileAccess(const std::string& filename,
permissions &= ~TEST_FILE_EXECUTE;
permissions |= TEST_FILE_READ;
}
- return _waccess(SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
+ return _waccess(Encoding::ToWindowsExtendedPath(filename).c_str(),
permissions) == 0;
#else
return access(filename.c_str(), permissions) == 0;
@@ -1258,6 +1256,38 @@ bool SystemTools::TestFileAccess(const std::string& filename,
}
//----------------------------------------------------------------------------
+int SystemTools::Stat(const char* path, SystemTools::Stat_t* buf)
+{
+ if (!path) {
+ errno = EFAULT;
+ return -1;
+ }
+ return SystemTools::Stat(std::string(path), buf);
+}
+
+//----------------------------------------------------------------------------
+int SystemTools::Stat(const std::string& path, SystemTools::Stat_t* buf)
+{
+ if (path.empty()) {
+ errno = ENOENT;
+ return -1;
+ }
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Ideally we should use Encoding::ToWindowsExtendedPath to support
+ // long paths, but _wstat64 rejects paths with '?' in them, thinking
+ // they are wildcards.
+ std::wstring const& wpath = Encoding::ToWide(path);
+#if defined(__BORLANDC__)
+ return _wstati64(wpath.c_str(), buf);
+#else
+ return _wstat64(wpath.c_str(), buf);
+#endif
+#else
+ return stat(path.c_str(), buf);
+#endif
+}
+
+//----------------------------------------------------------------------------
#ifdef __CYGWIN__
bool SystemTools::PathCygwinToWin32(const char* path, char* win32_path)
{
@@ -1293,10 +1323,9 @@ bool SystemTools::Touch(const std::string& filename, bool create)
}
}
#if defined(_WIN32) && !defined(__CYGWIN__)
- HANDLE h =
- CreateFileW(SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
- FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, 0, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS, 0);
+ HANDLE h = CreateFileW(Encoding::ToWindowsExtendedPath(filename).c_str(),
+ FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, 0,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
if (!h) {
return false;
}
@@ -1394,14 +1423,12 @@ bool SystemTools::FileTimeCompare(const std::string& f1, const std::string& f2,
// Windows version. Get the modification time from extended file attributes.
WIN32_FILE_ATTRIBUTE_DATA f1d;
WIN32_FILE_ATTRIBUTE_DATA f2d;
- if (!GetFileAttributesExW(
- SystemTools::ConvertToWindowsExtendedPath(f1).c_str(),
- GetFileExInfoStandard, &f1d)) {
+ if (!GetFileAttributesExW(Encoding::ToWindowsExtendedPath(f1).c_str(),
+ GetFileExInfoStandard, &f1d)) {
return false;
}
- if (!GetFileAttributesExW(
- SystemTools::ConvertToWindowsExtendedPath(f2).c_str(),
- GetFileExInfoStandard, &f2d)) {
+ if (!GetFileAttributesExW(Encoding::ToWindowsExtendedPath(f2).c_str(),
+ GetFileExInfoStandard, &f2d)) {
return false;
}
@@ -1929,59 +1956,10 @@ void SystemTools::ConvertToUnixSlashes(std::string& path)
}
#ifdef _WIN32
-// Convert local paths to UNC style paths
std::wstring SystemTools::ConvertToWindowsExtendedPath(
const std::string& source)
{
- std::wstring wsource = Encoding::ToWide(source);
-
- // Resolve any relative paths
- DWORD wfull_len;
-
- /* The +3 is a workaround for a bug in some versions of GetFullPathNameW that
- * won't return a large enough buffer size if the input is too small */
- wfull_len = GetFullPathNameW(wsource.c_str(), 0, NULL, NULL) + 3;
- std::vector<wchar_t> wfull(wfull_len);
- GetFullPathNameW(wsource.c_str(), wfull_len, &wfull[0], NULL);
-
- /* This should get the correct size without any extra padding from the
- * previous size workaround. */
- wfull_len = static_cast<DWORD>(wcslen(&wfull[0]));
-
- if (wfull_len >= 2 && isalpha(wfull[0]) &&
- wfull[1] == L':') { /* C:\Foo\bar\FooBar.txt */
- return L"\\\\?\\" + std::wstring(&wfull[0]);
- } else if (wfull_len >= 2 && wfull[0] == L'\\' &&
- wfull[1] == L'\\') { /* Starts with \\ */
- if (wfull_len >= 4 && wfull[2] == L'?' &&
- wfull[3] == L'\\') { /* Starts with \\?\ */
- if (wfull_len >= 8 && wfull[4] == L'U' && wfull[5] == L'N' &&
- wfull[6] == L'C' &&
- wfull[7] == L'\\') { /* \\?\UNC\Foo\bar\FooBar.txt */
- return std::wstring(&wfull[0]);
- } else if (wfull_len >= 6 && isalpha(wfull[4]) &&
- wfull[5] == L':') { /* \\?\C:\Foo\bar\FooBar.txt */
- return std::wstring(&wfull[0]);
- } else if (wfull_len >= 5) { /* \\?\Foo\bar\FooBar.txt */
- return L"\\\\?\\UNC\\" + std::wstring(&wfull[4]);
- }
- } else if (wfull_len >= 4 && wfull[2] == L'.' &&
- wfull[3] == L'\\') { /* Starts with \\.\ a device name */
- if (wfull_len >= 6 && isalpha(wfull[4]) &&
- wfull[5] == L':') { /* \\.\C:\Foo\bar\FooBar.txt */
- return L"\\\\?\\" + std::wstring(&wfull[4]);
- } else if (wfull_len >=
- 5) { /* \\.\Foo\bar\ Device name is left unchanged */
- return std::wstring(&wfull[0]);
- }
- } else if (wfull_len >= 3) { /* \\Foo\bar\FooBar.txt */
- return L"\\\\?\\UNC\\" + std::wstring(&wfull[2]);
- }
- }
-
- // If this case has been reached, then the path is invalid. Leave it
- // unchanged
- return Encoding::ToWide(source);
+ return Encoding::ToWindowsExtendedPath(source);
}
#endif
@@ -2098,15 +2076,14 @@ bool SystemTools::FilesDiffer(const std::string& source,
#if defined(_WIN32)
WIN32_FILE_ATTRIBUTE_DATA statSource;
- if (GetFileAttributesExW(
- SystemTools::ConvertToWindowsExtendedPath(source).c_str(),
- GetFileExInfoStandard, &statSource) == 0) {
+ if (GetFileAttributesExW(Encoding::ToWindowsExtendedPath(source).c_str(),
+ GetFileExInfoStandard, &statSource) == 0) {
return true;
}
WIN32_FILE_ATTRIBUTE_DATA statDestination;
if (GetFileAttributesExW(
- SystemTools::ConvertToWindowsExtendedPath(destination).c_str(),
+ Encoding::ToWindowsExtendedPath(destination).c_str(),
GetFileExInfoStandard, &statDestination) == 0) {
return true;
}
@@ -2230,8 +2207,7 @@ bool SystemTools::CopyFileAlways(const std::string& source,
// Open files
#if defined(_WIN32)
kwsys::ifstream fin(
- Encoding::ToNarrow(SystemTools::ConvertToWindowsExtendedPath(source))
- .c_str(),
+ Encoding::ToNarrow(Encoding::ToWindowsExtendedPath(source)).c_str(),
std::ios::in | std::ios::binary);
#else
kwsys::ifstream fin(source.c_str(), std::ios::in | std::ios::binary);
@@ -2248,8 +2224,7 @@ bool SystemTools::CopyFileAlways(const std::string& source,
#if defined(_WIN32)
kwsys::ofstream fout(
- Encoding::ToNarrow(
- SystemTools::ConvertToWindowsExtendedPath(real_destination))
+ Encoding::ToNarrow(Encoding::ToWindowsExtendedPath(real_destination))
.c_str(),
std::ios::out | std::ios::trunc | std::ios::binary);
#else
@@ -2314,8 +2289,7 @@ bool SystemTools::CopyADirectory(const std::string& source,
{
Directory dir;
#ifdef _WIN32
- dir.Load(
- Encoding::ToNarrow(SystemTools::ConvertToWindowsExtendedPath(source)));
+ dir.Load(Encoding::ToNarrow(Encoding::ToWindowsExtendedPath(source)));
#else
dir.Load(source);
#endif
@@ -2353,9 +2327,8 @@ unsigned long SystemTools::FileLength(const std::string& filename)
unsigned long length = 0;
#ifdef _WIN32
WIN32_FILE_ATTRIBUTE_DATA fs;
- if (GetFileAttributesExW(
- SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
- GetFileExInfoStandard, &fs) != 0) {
+ if (GetFileAttributesExW(Encoding::ToWindowsExtendedPath(filename).c_str(),
+ GetFileExInfoStandard, &fs) != 0) {
/* To support the full 64-bit file size, use fs.nFileSizeHigh
* and fs.nFileSizeLow to construct the 64 bit size
@@ -2389,9 +2362,8 @@ long int SystemTools::ModifiedTime(const std::string& filename)
long int mt = 0;
#ifdef _WIN32
WIN32_FILE_ATTRIBUTE_DATA fs;
- if (GetFileAttributesExW(
- SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
- GetFileExInfoStandard, &fs) != 0) {
+ if (GetFileAttributesExW(Encoding::ToWindowsExtendedPath(filename).c_str(),
+ GetFileExInfoStandard, &fs) != 0) {
mt = windows_filetime_to_posix_time(fs.ftLastWriteTime);
}
#else
@@ -2409,9 +2381,8 @@ long int SystemTools::CreationTime(const std::string& filename)
long int ct = 0;
#ifdef _WIN32
WIN32_FILE_ATTRIBUTE_DATA fs;
- if (GetFileAttributesExW(
- SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
- GetFileExInfoStandard, &fs) != 0) {
+ if (GetFileAttributesExW(Encoding::ToWindowsExtendedPath(filename).c_str(),
+ GetFileExInfoStandard, &fs) != 0) {
ct = windows_filetime_to_posix_time(fs.ftCreationTime);
}
#else
@@ -2625,7 +2596,7 @@ static bool DeleteJunction(const std::wstring& source)
bool SystemTools::RemoveFile(const std::string& source)
{
#ifdef _WIN32
- std::wstring const& ws = SystemTools::ConvertToWindowsExtendedPath(source);
+ std::wstring const& ws = Encoding::ToWindowsExtendedPath(source);
if (DeleteFileW(ws.c_str())) {
return true;
}
@@ -2675,8 +2646,7 @@ bool SystemTools::RemoveADirectory(const std::string& source)
Directory dir;
#ifdef _WIN32
- dir.Load(
- Encoding::ToNarrow(SystemTools::ConvertToWindowsExtendedPath(source)));
+ dir.Load(Encoding::ToNarrow(Encoding::ToWindowsExtendedPath(source)));
#else
dir.Load(source);
#endif
@@ -3033,8 +3003,8 @@ bool SystemTools::FileIsDirectory(const std::string& inName)
// Now check the file node type.
#if defined(_WIN32)
- DWORD attr = GetFileAttributesW(
- SystemTools::ConvertToWindowsExtendedPath(name).c_str());
+ DWORD attr =
+ GetFileAttributesW(Encoding::ToWindowsExtendedPath(name).c_str());
if (attr != INVALID_FILE_ATTRIBUTES) {
return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
#else
@@ -3050,8 +3020,8 @@ bool SystemTools::FileIsDirectory(const std::string& inName)
bool SystemTools::FileIsSymlink(const std::string& name)
{
#if defined(_WIN32)
- DWORD attr = GetFileAttributesW(
- SystemTools::ConvertToWindowsExtendedPath(name).c_str());
+ DWORD attr =
+ GetFileAttributesW(Encoding::ToWindowsExtendedPath(name).c_str());
if (attr != INVALID_FILE_ATTRIBUTES) {
return (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
} else {
@@ -3067,6 +3037,28 @@ bool SystemTools::FileIsSymlink(const std::string& name)
#endif
}
+bool SystemTools::FileIsFIFO(const std::string& name)
+{
+#if defined(_WIN32)
+ HANDLE hFile =
+ CreateFileW(Encoding::ToWide(name).c_str(), GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ return false;
+ }
+ const DWORD type = GetFileType(hFile);
+ CloseHandle(hFile);
+ return type == FILE_TYPE_PIPE;
+#else
+ struct stat fs;
+ if (lstat(name.c_str(), &fs) == 0) {
+ return S_ISFIFO(fs.st_mode);
+ } else {
+ return false;
+ }
+#endif
+}
+
#if defined(_WIN32) && !defined(__CYGWIN__)
bool SystemTools::CreateSymlink(const std::string&, const std::string&)
{
@@ -3309,7 +3301,7 @@ std::string SystemTools::CollapseFullPath(const std::string& in_path,
SystemTools::SplitPath(in_path, path_components);
// If the input path is relative, start with a base path.
- if (path_components[0].length() == 0) {
+ if (path_components[0].empty()) {
std::vector<std::string> base_components;
if (in_base) {
// Use the given base path.
@@ -4345,8 +4337,8 @@ bool SystemTools::GetPermissions(const char* file, mode_t& mode)
bool SystemTools::GetPermissions(const std::string& file, mode_t& mode)
{
#if defined(_WIN32)
- DWORD attr = GetFileAttributesW(
- SystemTools::ConvertToWindowsExtendedPath(file).c_str());
+ DWORD attr =
+ GetFileAttributesW(Encoding::ToWindowsExtendedPath(file).c_str());
if (attr == INVALID_FILE_ATTRIBUTES) {
return false;
}
@@ -4398,8 +4390,7 @@ bool SystemTools::SetPermissions(const std::string& file, mode_t mode,
mode &= ~currentMask;
}
#ifdef _WIN32
- if (_wchmod(SystemTools::ConvertToWindowsExtendedPath(file).c_str(), mode) <
- 0)
+ if (_wchmod(Encoding::ToWindowsExtendedPath(file).c_str(), mode) < 0)
#else
if (chmod(file.c_str(), mode) < 0)
#endif
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index f3d06fe..0849e1d 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -13,6 +13,9 @@
#include <@KWSYS_NAMESPACE@/String.hxx>
#include <sys/types.h>
+// include sys/stat.h after sys/types.h
+#include <sys/stat.h>
+
#if !defined(_WIN32) || defined(__CYGWIN__)
#include <unistd.h> // For access permissions for use with access()
#endif
@@ -262,13 +265,7 @@ public:
static void ConvertToUnixSlashes(std::string& path);
#ifdef _WIN32
- /**
- * Convert the path to an extended length path to avoid MAX_PATH length
- * limitations on Windows. If the input is a local path the result will be
- * prefixed with \\?\; if the input is instead a network path, the result
- * will be prefixed with \\?\UNC\. All output will also be converted to
- * absolute paths with Windows-style backslashes.
- **/
+ /** Calls Encoding::ToWindowsExtendedPath. */
static std::wstring ConvertToWindowsExtendedPath(const std::string&);
#endif
@@ -324,6 +321,27 @@ public:
TestFilePermissions permissions);
static bool TestFileAccess(const std::string& filename,
TestFilePermissions permissions);
+/**
+ * Cross platform wrapper for stat struct
+ */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(__BORLANDC__)
+ typedef struct stati64 Stat_t;
+#else
+ typedef struct _stat64 Stat_t;
+#endif
+#else
+ typedef struct stat Stat_t;
+#endif
+
+ /**
+ * Cross platform wrapper for stat system call
+ *
+ * On Windows this may not work for paths longer than 250 characters
+ * due to limitations of the underlying '_wstat64' call.
+ */
+ static int Stat(const char* path, Stat_t* buf);
+ static int Stat(const std::string& path, Stat_t* buf);
/**
* Converts Cygwin path to Win32 path. Uses dictionary container for
@@ -654,6 +672,11 @@ public:
static bool FileIsSymlink(const std::string& name);
/**
+ * Return true if the file is a FIFO
+ */
+ static bool FileIsFIFO(const std::string& name);
+
+ /**
* Return true if the file has a given signature (first set of bytes)
*/
static bool FileHasSignature(const char* filename, const char* signature,
diff --git a/Source/kwsys/testEncoding.cxx b/Source/kwsys/testEncoding.cxx
index 03f2ec9..457e8a8 100644
--- a/Source/kwsys/testEncoding.cxx
+++ b/Source/kwsys/testEncoding.cxx
@@ -180,6 +180,88 @@ static int testCommandLineArguments()
return status;
}
+static int testToWindowsExtendedPath()
+{
+#ifdef _WIN32
+ int ret = 0;
+ if (kwsys::Encoding::ToWindowsExtendedPath(
+ "L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
+ L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
+ << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath(
+ "L:/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
+ L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"L:/Local Mojo/Hex Power Pack/Iffy Voodoo\"" << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath(
+ "\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
+ L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
+ << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath(
+ "//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
+ L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo\""
+ << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath("//") != L"//") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"//\"" << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath("\\\\.\\") != L"\\\\.\\") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"\\\\.\\\"" << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath("\\\\.\\X") != L"\\\\.\\X") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"\\\\.\\X\"" << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath("\\\\.\\X:") != L"\\\\?\\X:") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"\\\\.\\X:\"" << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath("\\\\.\\X:\\") !=
+ L"\\\\?\\X:\\") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"\\\\.\\X:\\\"" << std::endl;
+ ++ret;
+ }
+
+ if (kwsys::Encoding::ToWindowsExtendedPath("NUL") != L"\\\\.\\NUL") {
+ std::cout << "Problem with ToWindowsExtendedPath "
+ << "\"NUL\"" << std::endl;
+ ++ret;
+ }
+
+ return ret;
+#else
+ return 0;
+#endif
+}
+
//----------------------------------------------------------------------------
int testEncoding(int, char* [])
{
@@ -196,6 +278,7 @@ int testEncoding(int, char* [])
ret |= testRobustEncoding();
ret |= testCommandLineArguments();
ret |= testWithNulls();
+ ret |= testToWindowsExtendedPath();
return ret;
}
diff --git a/Source/kwsys/testSystemInformation.cxx b/Source/kwsys/testSystemInformation.cxx
index 86a1e1e..3a9217f 100644
--- a/Source/kwsys/testSystemInformation.cxx
+++ b/Source/kwsys/testSystemInformation.cxx
@@ -52,6 +52,7 @@ int testSystemInformation(int, char* [])
printMethod(info, GetOSRelease);
printMethod(info, GetOSVersion);
printMethod(info, GetOSPlatform);
+ printMethod(info, Is64Bits);
printMethod(info, GetVendorString);
printMethod(info, GetVendorID);
printMethod(info, GetTypeID);
@@ -63,7 +64,6 @@ int testSystemInformation(int, char* [])
printMethod2(info, GetProcessorCacheSize, "KB");
printMethod(info, GetLogicalProcessorsPerPhysical);
printMethod2(info, GetProcessorClockFrequency, "MHz");
- printMethod(info, Is64Bits);
printMethod(info, GetNumberOfLogicalCPU);
printMethod(info, GetNumberOfPhysicalCPU);
printMethod(info, DoesCPUSupportCPUID);
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 8e1ea25..d11bcae 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -135,6 +135,19 @@ static bool CheckFileOperations()
res = false;
}
+ kwsys::SystemTools::Stat_t buf;
+ if (kwsys::SystemTools::Stat(testTxtFile.c_str(), &buf) != 0) {
+ std::cerr << "Problem with Stat - unable to stat text file: "
+ << testTxtFile << std::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::Stat(testBinFile, &buf) != 0) {
+ std::cerr << "Problem with Stat - unable to stat bin file: " << testBinFile
+ << std::endl;
+ res = false;
+ }
+
if (!kwsys::SystemTools::MakeDirectory(testNewDir)) {
std::cerr << "Problem with MakeDirectory for: " << testNewDir << std::endl;
res = false;
@@ -572,85 +585,6 @@ static bool CheckStringOperations()
res = false;
}
-#ifdef _WIN32
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath(
- "L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
- L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
- << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath(
- "L:/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
- L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"L:/Local Mojo/Hex Power Pack/Iffy Voodoo\"" << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath(
- "\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
- L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
- << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath(
- "//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
- L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo\""
- << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath("//") != L"//") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"//\"" << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\") !=
- L"\\\\.\\") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"\\\\.\\\"" << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X") !=
- L"\\\\.\\X") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"\\\\.\\X\"" << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X:") !=
- L"\\\\?\\X:") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"\\\\.\\X:\"" << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X:\\") !=
- L"\\\\?\\X:\\") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"\\\\.\\X:\\\"" << std::endl;
- res = false;
- }
-
- if (kwsys::SystemTools::ConvertToWindowsExtendedPath("NUL") !=
- L"\\\\.\\NUL") {
- std::cerr << "Problem with ConvertToWindowsExtendedPath "
- << "\"NUL\"" << std::endl;
- res = false;
- }
-
-#endif
-
if (kwsys::SystemTools::ConvertToWindowsOutputPath(
"L://Local Mojo/Hex Power Pack/Iffy Voodoo") !=
"\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"") {