From a2bf6bb3bb3fe006cf9a3975d372d81290e67bc4 Mon Sep 17 00:00:00 2001 From: Mathieu Westphal <mathieu.westphal@kitware.com> Date: Fri, 24 Mar 2017 14:59:55 +0100 Subject: [PATCH] SystemTools: Add cross-platform stat() wrapper --- SystemTools.cxx | 28 +++++++++++++++++++++++++++- SystemTools.hxx.in | 20 ++++++++++++++++++++ testSystemTools.cxx | 13 +++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/SystemTools.cxx b/SystemTools.cxx index 65b7b26..3b65185 100644 --- a/SystemTools.cxx +++ b/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__) @@ -1257,6 +1256,33 @@ bool SystemTools::TestFileAccess(const std::string& filename, #endif } +//---------------------------------------------------------------------------- +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 ConvertToWindowsExtendedPath to support + // long paths, but _wstat64 rejects paths with '?' in them, thinking + // they are wildcards. + return _wstat64(Encoding::ToWide(path).c_str(), buf); +#else + return stat(path.c_str(), buf); +#endif +} + //---------------------------------------------------------------------------- #ifdef __CYGWIN__ bool SystemTools::PathCygwinToWin32(const char* path, char* win32_path) diff --git a/SystemTools.hxx.in b/SystemTools.hxx.in index 7a5256b..bfd979d 100644 --- a/SystemTools.hxx.in +++ b/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 @@ -324,6 +327,23 @@ public: TestFilePermissions permissions); static bool TestFileAccess(const std::string& filename, TestFilePermissions permissions); +/** + * Cross platform wrapper for stat struct + */ +#if defined(_WIN32) && !defined(__CYGWIN__) + typedef struct _stat64 Stat_t; +#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 diff --git a/testSystemTools.cxx b/testSystemTools.cxx index 8e1ea25..9b08a04 100644 --- a/testSystemTools.cxx +++ b/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; -- GitLab