diff options
Diffstat (limited to 'Source/kwsys')
-rw-r--r-- | Source/kwsys/.gitattributes | 17 | ||||
-rw-r--r-- | Source/kwsys/CMakeLists.txt | 21 | ||||
-rw-r--r-- | Source/kwsys/ConsoleBuf.hxx.in | 3 | ||||
-rw-r--r-- | Source/kwsys/Encoding.hxx.in | 13 | ||||
-rw-r--r-- | Source/kwsys/EncodingCXX.cxx | 58 | ||||
-rw-r--r-- | Source/kwsys/FStream.hxx.in | 10 | ||||
-rw-r--r-- | Source/kwsys/SystemInformation.cxx | 281 | ||||
-rw-r--r-- | Source/kwsys/SystemInformation.hxx.in | 3 | ||||
-rw-r--r-- | Source/kwsys/SystemTools.cxx | 193 | ||||
-rw-r--r-- | Source/kwsys/SystemTools.hxx.in | 37 | ||||
-rw-r--r-- | Source/kwsys/testEncoding.cxx | 83 | ||||
-rw-r--r-- | Source/kwsys/testSystemInformation.cxx | 2 | ||||
-rw-r--r-- | Source/kwsys/testSystemTools.cxx | 92 |
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\"") { |