Merge branch 'upstream-kwsys' into update-kwsys

This commit is contained in:
Brad King 2015-08-31 09:55:01 -04:00
commit 49d293a795
6 changed files with 370 additions and 94 deletions

View File

@ -1 +0,0 @@
@CMAKE_EMPTY_INPUT_FILE_CONTENT@

View File

@ -91,6 +91,7 @@ ENDIF()
IF(POLICY CMP0056) IF(POLICY CMP0056)
CMAKE_POLICY(SET CMP0056 NEW) CMAKE_POLICY(SET CMP0056 NEW)
ENDIF() ENDIF()
SET(CMAKE_LEGACY_CYGWIN_WIN32 0)
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# If a namespace is not specified, use "kwsys" and enable testing. # If a namespace is not specified, use "kwsys" and enable testing.
@ -311,6 +312,15 @@ IF(NOT CMAKE_COMPILER_IS_GNUCXX)
ENDIF() ENDIF()
ENDIF() ENDIF()
ENDIF() ENDIF()
IF(KWSYS_STANDALONE)
IF(CMAKE_CXX_COMPILER_ID STREQUAL SunPro)
IF(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03")
ELSE()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4")
ENDIF()
ENDIF()
ENDIF()
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Configure Large File Support. # Configure Large File Support.
@ -1071,7 +1081,7 @@ IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
# Apply user-defined target properties to the library. # Apply user-defined target properties to the library.
IF(KWSYS_PROPERTIES_C) IF(KWSYS_PROPERTIES_C)
SET_TARGET_PROPERTIES(${KWSYS_NAMESPACE} PROPERTIES SET_TARGET_PROPERTIES(${KWSYS_NAMESPACE}_c PROPERTIES
${KWSYS_PROPERTIES_C} ${KWSYS_PROPERTIES_C}
) )
ENDIF() ENDIF()

View File

@ -68,6 +68,10 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <time.h> #include <time.h>
#ifdef _MSC_VER
# define umask _umask // Note this is still umask on Borland
#endif
// support for realpath call // support for realpath call
#ifndef _WIN32 #ifndef _WIN32
#include <sys/time.h> #include <sys/time.h>
@ -1233,13 +1237,11 @@ bool SystemTools::FileExists(const kwsys_stl::string& filename)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool SystemTools::FileExists(const char* filename, bool isFile) bool SystemTools::FileExists(const char* filename, bool isFile)
{ {
if(SystemTools::FileExists(filename)) if(!filename)
{ {
// If isFile is set return not FileIsDirectory, return false;
// so this will only be true if it is a file
return !isFile || !SystemTools::FileIsDirectory(filename);
} }
return false; return SystemTools::FileExists(kwsys_stl::string(filename), isFile);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1254,6 +1256,43 @@ bool SystemTools::FileExists(const kwsys_stl::string& filename, bool isFile)
return false; return false;
} }
//----------------------------------------------------------------------------
bool SystemTools::TestFileAccess(const char* filename,
TestFilePermissions permissions)
{
if(!filename)
{
return false;
}
return SystemTools::TestFileAccess(kwsys_stl::string(filename),
permissions);
}
//----------------------------------------------------------------------------
bool SystemTools::TestFileAccess(const kwsys_stl::string& filename,
TestFilePermissions permissions)
{
if(filename.empty())
{
return false;
}
#if defined(_WIN32) && !defined(__CYGWIN__)
// If execute set, change to read permission (all files on Windows
// are executable if they are readable). The CRT will always fail
// if you pass an execute bit.
if(permissions & TEST_FILE_EXECUTE)
{
permissions &= ~TEST_FILE_EXECUTE;
permissions |= TEST_FILE_READ;
}
return _waccess(
SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
permissions) == 0;
#else
return access(filename.c_str(), permissions) == 0;
#endif
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
#ifdef __CYGWIN__ #ifdef __CYGWIN__
bool SystemTools::PathCygwinToWin32(const char *path, char *win32_path) bool SystemTools::PathCygwinToWin32(const char *path, char *win32_path)
@ -4745,21 +4784,35 @@ bool SystemTools::GetPermissions(const kwsys_stl::string& file, mode_t& mode)
return true; return true;
} }
bool SystemTools::SetPermissions(const char* file, mode_t mode) bool SystemTools::SetPermissions(const char* file,
mode_t mode,
bool honor_umask)
{ {
if ( !file ) if ( !file )
{ {
return false; return false;
} }
return SystemTools::SetPermissions(kwsys_stl::string(file), mode); return SystemTools::SetPermissions(
kwsys_stl::string(file), mode, honor_umask);
} }
bool SystemTools::SetPermissions(const kwsys_stl::string& file, mode_t mode) bool SystemTools::SetPermissions(const kwsys_stl::string& file,
mode_t mode,
bool honor_umask)
{ {
if ( !SystemTools::FileExists(file) ) // TEMPORARY / TODO: After FileExists calls lstat() instead of
// access(), change this call to FileExists instead of
// TestFileAccess so that we don't follow symlinks.
if ( !SystemTools::TestFileAccess(file, TEST_FILE_OK) )
{ {
return false; return false;
} }
if (honor_umask)
{
mode_t currentMask = umask(0);
umask(currentMask);
mode &= ~currentMask;
}
#ifdef _WIN32 #ifdef _WIN32
if ( _wchmod(SystemTools::ConvertToWindowsExtendedPath(file).c_str(), if ( _wchmod(SystemTools::ConvertToWindowsExtendedPath(file).c_str(),
mode) < 0 ) mode) < 0 )

View File

@ -21,6 +21,9 @@
#include <@KWSYS_NAMESPACE@/String.hxx> #include <@KWSYS_NAMESPACE@/String.hxx>
#include <sys/types.h> #include <sys/types.h>
#if !defined(_WIN32) || defined(__CYGWIN__)
# include <unistd.h> // For access permissions for use with access()
#endif
// Required for va_list // Required for va_list
#include <stdarg.h> #include <stdarg.h>
@ -68,10 +71,28 @@ public:
}; };
// This instance will show up in any translation unit that uses // This instance will show up in any translation unit that uses
// SystemTools. It will make sure SystemTools is initialized // SystemTools. It will make sure SystemTools is initialized
// before it is used and is the last static object destroyed. // before it is used and is the last static object destroyed.
static SystemToolsManager SystemToolsManagerInstance; static SystemToolsManager SystemToolsManagerInstance;
// Flags for use with TestFileAccess. Use a typedef in case any operating
// system in the future needs a special type. These are flags that may be
// combined using the | operator.
typedef int TestFilePermissions;
#if defined(_WIN32) && !defined(__CYGWIN__)
// On Windows (VC and Borland), no system header defines these constants...
static const TestFilePermissions TEST_FILE_OK = 0;
static const TestFilePermissions TEST_FILE_READ = 4;
static const TestFilePermissions TEST_FILE_WRITE = 2;
static const TestFilePermissions TEST_FILE_EXECUTE = 1;
#else
// Standard POSIX constants
static const TestFilePermissions TEST_FILE_OK = F_OK;
static const TestFilePermissions TEST_FILE_READ = R_OK;
static const TestFilePermissions TEST_FILE_WRITE = W_OK;
static const TestFilePermissions TEST_FILE_EXECUTE = X_OK;
#endif
/** \class SystemTools /** \class SystemTools
* \brief A collection of useful platform-independent system functions. * \brief A collection of useful platform-independent system functions.
*/ */
@ -113,34 +134,34 @@ public:
* all other are lowercased). * all other are lowercased).
*/ */
static kwsys_stl::string Capitalized(const kwsys_stl::string&); static kwsys_stl::string Capitalized(const kwsys_stl::string&);
/** /**
* Return a 'capitalized words' string (i.e the first letter of each word * Return a 'capitalized words' string (i.e the first letter of each word
* is uppercased all other are left untouched though). * is uppercased all other are left untouched though).
*/ */
static kwsys_stl::string CapitalizedWords(const kwsys_stl::string&); static kwsys_stl::string CapitalizedWords(const kwsys_stl::string&);
/** /**
* Return a 'uncapitalized words' string (i.e the first letter of each word * Return a 'uncapitalized words' string (i.e the first letter of each word
* is lowercased all other are left untouched though). * is lowercased all other are left untouched though).
*/ */
static kwsys_stl::string UnCapitalizedWords(const kwsys_stl::string&); static kwsys_stl::string UnCapitalizedWords(const kwsys_stl::string&);
/** /**
* Return a lower case string * Return a lower case string
*/ */
static kwsys_stl::string LowerCase(const kwsys_stl::string&); static kwsys_stl::string LowerCase(const kwsys_stl::string&);
/** /**
* Return a lower case string * Return a lower case string
*/ */
static kwsys_stl::string UpperCase(const kwsys_stl::string&); static kwsys_stl::string UpperCase(const kwsys_stl::string&);
/** /**
* Count char in string * Count char in string
*/ */
static size_t CountChar(const char* str, char c); static size_t CountChar(const char* str, char c);
/** /**
* Remove some characters from a string. * Remove some characters from a string.
* Return a pointer to the new resulting string (allocated with 'new') * Return a pointer to the new resulting string (allocated with 'new')
@ -152,13 +173,13 @@ public:
* Return a pointer to the new resulting string (allocated with 'new') * Return a pointer to the new resulting string (allocated with 'new')
*/ */
static char* RemoveCharsButUpperHex(const char* str); static char* RemoveCharsButUpperHex(const char* str);
/** /**
* Replace some characters by another character in a string (in-place) * Replace some characters by another character in a string (in-place)
* Return a pointer to string * Return a pointer to string
*/ */
static char* ReplaceChars(char* str, const char *toreplace,char replacement); static char* ReplaceChars(char* str, const char *toreplace,char replacement);
/** /**
* Returns true if str1 starts (respectively ends) with str2 * Returns true if str1 starts (respectively ends) with str2
*/ */
@ -171,25 +192,25 @@ public:
* Returns a pointer to the last occurence of str2 in str1 * Returns a pointer to the last occurence of str2 in str1
*/ */
static const char* FindLastString(const char* str1, const char* str2); static const char* FindLastString(const char* str1, const char* str2);
/** /**
* Make a duplicate of the string similar to the strdup C function * Make a duplicate of the string similar to the strdup C function
* but use new to create the 'new' string, so one can use * but use new to create the 'new' string, so one can use
* 'delete' to remove it. Returns 0 if the input is empty. * 'delete' to remove it. Returns 0 if the input is empty.
*/ */
static char* DuplicateString(const char* str); static char* DuplicateString(const char* str);
/** /**
* Return the string cropped to a given length by removing chars in the * Return the string cropped to a given length by removing chars in the
* center of the string and replacing them with an ellipsis (...) * center of the string and replacing them with an ellipsis (...)
*/ */
static kwsys_stl::string CropString(const kwsys_stl::string&,size_t max_len); static kwsys_stl::string CropString(const kwsys_stl::string&,size_t max_len);
/** split a path by separator into an array of strings, default is /. /** split a path by separator into an array of strings, default is /.
If isPath is true then the string is treated like a path and if If isPath is true then the string is treated like a path and if
s starts with a / then the first element of the returned array will s starts with a / then the first element of the returned array will
be /, so /foo/bar will be [/, foo, bar] be /, so /foo/bar will be [/, foo, bar]
*/ */
static kwsys_stl::vector<String> SplitString(const kwsys_stl::string& s, char separator = '/', static kwsys_stl::vector<String> SplitString(const kwsys_stl::string& s, char separator = '/',
bool isPath = false); bool isPath = false);
/** /**
@ -197,7 +218,7 @@ public:
*/ */
static int Strucmp(const char *s1, const char *s2); static int Strucmp(const char *s1, const char *s2);
/** /**
* Convert a string in __DATE__ or __TIMESTAMP__ format into a time_t. * Convert a string in __DATE__ or __TIMESTAMP__ format into a time_t.
* Return false on error, true on success * Return false on error, true on success
*/ */
@ -210,11 +231,11 @@ public:
*/ */
static bool Split(const kwsys_stl::string& s, kwsys_stl::vector<kwsys_stl::string>& l); static bool Split(const kwsys_stl::string& s, kwsys_stl::vector<kwsys_stl::string>& l);
static bool Split(const kwsys_stl::string& s, kwsys_stl::vector<kwsys_stl::string>& l, char separator); static bool Split(const kwsys_stl::string& s, kwsys_stl::vector<kwsys_stl::string>& l, char separator);
/** /**
* Return string with space added between capitalized words * Return string with space added between capitalized words
* (i.e. EatMyShorts becomes Eat My Shorts ) * (i.e. EatMyShorts becomes Eat My Shorts )
* (note that IEatShorts becomes IEat Shorts) * (note that IEatShorts becomes IEat Shorts)
*/ */
static kwsys_stl::string AddSpaceBetweenCapitalizedWords( static kwsys_stl::string AddSpaceBetweenCapitalizedWords(
const kwsys_stl::string&); const kwsys_stl::string&);
@ -290,15 +311,32 @@ public:
/** /**
* Return true if a file exists in the current directory. * Return true if a file exists in the current directory.
* If isFile = true, then make sure the file is a file and * If isFile = true, then make sure the file is a file and
* not a directory. If isFile = false, then return true * not a directory. If isFile = false, then return true
* if it is a file or a directory. * if it is a file or a directory. Note that the file will
* also be checked for read access. (Currently, this check
* for read access is only done on POSIX systems.)
*/ */
static bool FileExists(const char* filename, bool isFile); static bool FileExists(const char* filename, bool isFile);
static bool FileExists(const kwsys_stl::string& filename, bool isFile); static bool FileExists(const kwsys_stl::string& filename, bool isFile);
static bool FileExists(const char* filename); static bool FileExists(const char* filename);
static bool FileExists(const kwsys_stl::string& filename); static bool FileExists(const kwsys_stl::string& filename);
/**
* Test if a file exists and can be accessed with the requested
* permissions. Symbolic links are followed. Returns true if
* the access test was successful.
*
* On POSIX systems (including Cygwin), this maps to the access
* function. On Windows systems, all existing files are
* considered readable, and writable files are considered to
* have the read-only file attribute cleared.
*/
static bool TestFileAccess(const char* filename,
TestFilePermissions permissions);
static bool TestFileAccess(const kwsys_stl::string& filename,
TestFilePermissions permissions);
/** /**
* Converts Cygwin path to Win32 path. Uses dictionary container for * Converts Cygwin path to Win32 path. Uses dictionary container for
* caching and calls to cygwin_conv_to_win32_path from Cygwin dll * caching and calls to cygwin_conv_to_win32_path from Cygwin dll
@ -317,7 +355,7 @@ public:
Change the modification time or create a file Change the modification time or create a file
*/ */
static bool Touch(const kwsys_stl::string& filename, bool create); static bool Touch(const kwsys_stl::string& filename, bool create);
/** /**
* Compare file modification times. * Compare file modification times.
* Return true for successful comparison and false for error. * Return true for successful comparison and false for error.
@ -360,7 +398,7 @@ public:
* to the running executable. If argv0 is not a full path, * to the running executable. If argv0 is not a full path,
* then this will try to find the full path. If the path is not * then this will try to find the full path. If the path is not
* found false is returned, if found true is returned. An error * found false is returned, if found true is returned. An error
* message of the attempted paths is stored in errorMsg. * message of the attempted paths is stored in errorMsg.
* exeName is the name of the executable. * exeName is the name of the executable.
* buildDir is a possibly null path to the build directory. * buildDir is a possibly null path to the build directory.
* installPrefix is a possibly null pointer to the install directory. * installPrefix is a possibly null pointer to the install directory.
@ -384,7 +422,7 @@ public:
static kwsys_stl::string CollapseFullPath(const kwsys_stl::string& in_relative, static kwsys_stl::string CollapseFullPath(const kwsys_stl::string& in_relative,
const kwsys_stl::string& in_base); const kwsys_stl::string& in_base);
/** /**
* Get the real path for a given path, removing all symlinks. In * Get the real path for a given path, removing all symlinks. In
* the event of an error (non-existent path, permissions issue, * the event of an error (non-existent path, permissions issue,
* etc.) the original path is returned if errorMessage pointer is * etc.) the original path is returned if errorMessage pointer is
@ -469,31 +507,31 @@ public:
*/ */
static kwsys_stl::string GetFilenameLastExtension( static kwsys_stl::string GetFilenameLastExtension(
const kwsys_stl::string& filename); const kwsys_stl::string& filename);
/** /**
* Return file name without extension of a full filename * Return file name without extension of a full filename
*/ */
static kwsys_stl::string GetFilenameWithoutExtension( static kwsys_stl::string GetFilenameWithoutExtension(
const kwsys_stl::string&); const kwsys_stl::string&);
/** /**
* Return file name without its last (shortest) extension * Return file name without its last (shortest) extension
*/ */
static kwsys_stl::string GetFilenameWithoutLastExtension( static kwsys_stl::string GetFilenameWithoutLastExtension(
const kwsys_stl::string&); const kwsys_stl::string&);
/** /**
* Return whether the path represents a full path (not relative) * Return whether the path represents a full path (not relative)
*/ */
static bool FileIsFullPath(const kwsys_stl::string&); static bool FileIsFullPath(const kwsys_stl::string&);
static bool FileIsFullPath(const char*); static bool FileIsFullPath(const char*);
/** /**
* For windows return the short path for the given path, * For windows return the short path for the given path,
* Unix just a pass through * Unix just a pass through
*/ */
static bool GetShortPath(const kwsys_stl::string& path, kwsys_stl::string& result); static bool GetShortPath(const kwsys_stl::string& path, kwsys_stl::string& result);
/** /**
* Read line from file. Make sure to get everything. Due to a buggy stream * Read line from file. Make sure to get everything. Due to a buggy stream
* library on the HP and another on Mac OS X, we need this very carefully * library on the HP and another on Mac OS X, we need this very carefully
@ -501,7 +539,7 @@ public:
* end-of-file was reached. If the has_newline argument is specified, it will * end-of-file was reached. If the has_newline argument is specified, it will
* be true when the line read had a newline character. * be true when the line read had a newline character.
*/ */
static bool GetLineFromStream(kwsys_ios::istream& istr, static bool GetLineFromStream(kwsys_ios::istream& istr,
kwsys_stl::string& line, kwsys_stl::string& line,
bool* has_newline=0, bool* has_newline=0,
long sizeLimit=-1); long sizeLimit=-1);
@ -529,7 +567,7 @@ public:
/** /**
* Make a new directory if it is not there. This function * Make a new directory if it is not there. This function
* can make a full path even if none of the directories existed * can make a full path even if none of the directories existed
* prior to calling this function. * prior to calling this function.
*/ */
static bool MakeDirectory(const char* path); static bool MakeDirectory(const char* path);
static bool MakeDirectory(const kwsys_stl::string& path); static bool MakeDirectory(const kwsys_stl::string& path);
@ -572,12 +610,12 @@ public:
*/ */
static bool CopyADirectory(const kwsys_stl::string& source, const kwsys_stl::string& destination, static bool CopyADirectory(const kwsys_stl::string& source, const kwsys_stl::string& destination,
bool always = true); bool always = true);
/** /**
* Remove a file * Remove a file
*/ */
static bool RemoveFile(const kwsys_stl::string& source); static bool RemoveFile(const kwsys_stl::string& source);
/** /**
* Remove a directory * Remove a directory
*/ */
@ -593,7 +631,7 @@ public:
*/ */
static kwsys_stl::string FindFile( static kwsys_stl::string FindFile(
const kwsys_stl::string& name, const kwsys_stl::string& name,
const kwsys_stl::vector<kwsys_stl::string>& path = const kwsys_stl::vector<kwsys_stl::string>& path =
kwsys_stl::vector<kwsys_stl::string>(), kwsys_stl::vector<kwsys_stl::string>(),
bool no_system_path = false); bool no_system_path = false);
@ -602,7 +640,7 @@ public:
*/ */
static kwsys_stl::string FindDirectory( static kwsys_stl::string FindDirectory(
const kwsys_stl::string& name, const kwsys_stl::string& name,
const kwsys_stl::vector<kwsys_stl::string>& path = const kwsys_stl::vector<kwsys_stl::string>& path =
kwsys_stl::vector<kwsys_stl::string>(), kwsys_stl::vector<kwsys_stl::string>(),
bool no_system_path = false); bool no_system_path = false);
@ -631,17 +669,17 @@ public:
static kwsys_stl::string FindLibrary( static kwsys_stl::string FindLibrary(
const kwsys_stl::string& name, const kwsys_stl::string& name,
const kwsys_stl::vector<kwsys_stl::string>& path); const kwsys_stl::vector<kwsys_stl::string>& path);
/** /**
* Return true if the file is a directory * Return true if the file is a directory
*/ */
static bool FileIsDirectory(const kwsys_stl::string& name); static bool FileIsDirectory(const kwsys_stl::string& name);
/** /**
* Return true if the file is a symlink * Return true if the file is a symlink
*/ */
static bool FileIsSymlink(const kwsys_stl::string& name); static bool FileIsSymlink(const kwsys_stl::string& name);
/** /**
* Return true if the file has a given signature (first set of bytes) * Return true if the file has a given signature (first set of bytes)
*/ */
@ -657,15 +695,15 @@ public:
* The algorithm is simplistic, and should probably check for usual file * The algorithm is simplistic, and should probably check for usual file
* extensions, 'magic' signature, unicode, etc. * extensions, 'magic' signature, unicode, etc.
*/ */
enum FileTypeEnum enum FileTypeEnum
{ {
FileTypeUnknown, FileTypeUnknown,
FileTypeBinary, FileTypeBinary,
FileTypeText FileTypeText
}; };
static SystemTools::FileTypeEnum DetectFileType( static SystemTools::FileTypeEnum DetectFileType(
const char* filename, const char* filename,
unsigned long length = 256, unsigned long length = 256,
double percent_bin = 0.05); double percent_bin = 0.05);
/** /**
@ -690,18 +728,18 @@ public:
* 'filename_found' is assigned the fully qualified name/path of the file * 'filename_found' is assigned the fully qualified name/path of the file
* if it is found (not touched otherwise). * if it is found (not touched otherwise).
* If 'try_filename_dirs' is true, try to find the file using the * If 'try_filename_dirs' is true, try to find the file using the
* components of its path, i.e. if we are looking for c:/foo/bar/bill.txt, * components of its path, i.e. if we are looking for c:/foo/bar/bill.txt,
* first look for bill.txt in 'dir', then in 'dir'/bar, then in 'dir'/foo/bar * first look for bill.txt in 'dir', then in 'dir'/bar, then in 'dir'/foo/bar
* etc. * etc.
* Return true if the file was found, false otherwise. * Return true if the file was found, false otherwise.
*/ */
static bool LocateFileInDir(const char *filename, static bool LocateFileInDir(const char *filename,
const char *dir, const char *dir,
kwsys_stl::string& filename_found, kwsys_stl::string& filename_found,
int try_filename_dirs = 0); int try_filename_dirs = 0);
/** compute the relative path from local to remote. local must /** compute the relative path from local to remote. local must
be a directory. remote can be a file or a directory. be a directory. remote can be a file or a directory.
Both remote and local must be full paths. Basically, if Both remote and local must be full paths. Basically, if
you are in directory local and you want to access the file in remote you are in directory local and you want to access the file in remote
what is the relative path to do that. For example: what is the relative path to do that. For example:
@ -720,17 +758,27 @@ public:
*/ */
static long int CreationTime(const kwsys_stl::string& filename); static long int CreationTime(const kwsys_stl::string& filename);
/**
* Visual C++ does not define mode_t (note that Borland does, however).
*/
#if defined( _MSC_VER ) #if defined( _MSC_VER )
typedef unsigned short mode_t; typedef unsigned short mode_t;
#endif #endif
/** /**
* Get and set permissions of the file. * Get and set permissions of the file. If honor_umask is set, the umask
* is queried and applied to the given permissions. Returns false if
* failure.
*
* WARNING: A non-thread-safe method is currently used to get the umask
* if a honor_umask parameter is set to true.
*/ */
static bool GetPermissions(const char* file, mode_t& mode); static bool GetPermissions(const char* file, mode_t& mode);
static bool GetPermissions(const kwsys_stl::string& file, mode_t& mode); static bool GetPermissions(const kwsys_stl::string& file, mode_t& mode);
static bool SetPermissions(const char* file, mode_t mode); static bool SetPermissions(
static bool SetPermissions(const kwsys_stl::string& file, mode_t mode); const char* file, mode_t mode, bool honor_umask = false);
static bool SetPermissions(
const kwsys_stl::string& file, mode_t mode, bool honor_umask = false);
/** ----------------------------------------------------------------- /** -----------------------------------------------------------------
* Time Manipulation Routines * Time Manipulation Routines
@ -891,11 +939,11 @@ public:
* Return true if the string matches the format; false otherwise. * Return true if the string matches the format; false otherwise.
*/ */
static bool ParseURL( const kwsys_stl::string& URL, static bool ParseURL( const kwsys_stl::string& URL,
kwsys_stl::string& protocol, kwsys_stl::string& protocol,
kwsys_stl::string& username, kwsys_stl::string& username,
kwsys_stl::string& password, kwsys_stl::string& password,
kwsys_stl::string& hostname, kwsys_stl::string& hostname,
kwsys_stl::string& dataport, kwsys_stl::string& dataport,
kwsys_stl::string& datapath ); kwsys_stl::string& datapath );
private: private:
@ -936,7 +984,7 @@ private:
*/ */
static kwsys_stl::string FindName( static kwsys_stl::string FindName(
const kwsys_stl::string& name, const kwsys_stl::string& name,
const kwsys_stl::vector<kwsys_stl::string>& path = const kwsys_stl::vector<kwsys_stl::string>& path =
kwsys_stl::vector<kwsys_stl::string>(), kwsys_stl::vector<kwsys_stl::string>(),
bool no_system_path = false); bool no_system_path = false);

View File

@ -21,6 +21,7 @@
#endif #endif
#include <assert.h> #include <assert.h>
#include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -74,6 +75,16 @@ int runChild(const char* cmd[], int state, int exception, int value,
static int test1(int argc, const char* argv[]) static int test1(int argc, const char* argv[])
{ {
/* This is a very basic functional test of kwsysProcess. It is repeated
numerous times to verify that there are no resource leaks in kwsysProcess
that eventually lead to an error. Many versions of OS X will fail after
256 leaked file handles, so 257 iterations seems to be a good test. On
the other hand, too many iterations will cause the test to time out -
especially if the test is instrumented with e.g. valgrind.
If you have problems with this test timing out on your system, or want to
run more than 257 iterations, you can change the number of iterations by
setting the KWSYS_TEST_PROCESS_1_COUNT environment variable. */
(void)argc; (void)argv; (void)argc; (void)argv;
fprintf(stdout, "Output on stdout from test returning 0.\n"); fprintf(stdout, "Output on stdout from test returning 0.\n");
fprintf(stderr, "Output on stderr from test returning 0.\n"); fprintf(stderr, "Output on stderr from test returning 0.\n");
@ -557,6 +568,10 @@ int runChild(const char* cmd[], int state, int exception, int value,
result = runChild2(kp, cmd, state, exception, value, share, result = runChild2(kp, cmd, state, exception, value, share,
output, delay, timeout, poll, disown, createNewGroup, output, delay, timeout, poll, disown, createNewGroup,
interruptDelay); interruptDelay);
if(result)
{
break;
}
} }
kwsysProcess_Delete(kp); kwsysProcess_Delete(kp);
return result; return result;
@ -660,13 +675,24 @@ int main(int argc, const char* argv[])
int delays[10] = {0, 0, 0, 0, 0, 1, 0, 0, 0, 0}; int delays[10] = {0, 0, 0, 0, 0, 1, 0, 0, 0, 0};
double timeouts[10] = {10, 10, 10, 30, 30, 10, -1, 10, 6, 4}; double timeouts[10] = {10, 10, 10, 30, 30, 10, -1, 10, 6, 4};
int polls[10] = {0, 0, 0, 0, 0, 0, 1, 0, 0, 0}; int polls[10] = {0, 0, 0, 0, 0, 0, 1, 0, 0, 0};
int repeat[10] = {2, 1, 1, 1, 1, 1, 1, 1, 1, 1}; int repeat[10] = {257, 1, 1, 1, 1, 1, 1, 1, 1, 1};
int createNewGroups[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1}; int createNewGroups[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1};
unsigned int interruptDelays[10] = {0, 0, 0, 0, 0, 0, 0, 0, 3, 2}; unsigned int interruptDelays[10] = {0, 0, 0, 0, 0, 0, 0, 0, 3, 2};
int r; int r;
const char* cmd[4]; const char* cmd[4];
#ifdef _WIN32 #ifdef _WIN32
char* argv0 = 0; char* argv0 = 0;
#endif
char* test1IterationsStr = getenv("KWSYS_TEST_PROCESS_1_COUNT");
if(test1IterationsStr)
{
long int test1Iterations = strtol(test1IterationsStr, 0, 10);
if(test1Iterations > 10 && test1Iterations != LONG_MAX)
{
repeat[0] = (int)test1Iterations;
}
}
#ifdef _WIN32
if(n == 0 && (argv0 = strdup(argv[0]))) if(n == 0 && (argv0 = strdup(argv[0])))
{ {
/* Try converting to forward slashes to see if it works. */ /* Try converting to forward slashes to see if it works. */

View File

@ -30,6 +30,17 @@
#include <testSystemTools.h> #include <testSystemTools.h>
#include <string.h> /* strcmp */ #include <string.h> /* strcmp */
#if defined(_WIN32) && !defined(__CYGWIN__)
# include <io.h> /* _umask (MSVC) / umask (Borland) */
# ifdef _MSC_VER
# define umask _umask // Note this is still umask on Borland
# endif
#endif
#include <sys/stat.h> /* umask (POSIX), _S_I* constants (Windows) */
// Visual C++ does not define mode_t (note that Borland does, however).
#if defined( _MSC_VER )
typedef unsigned short mode_t;
#endif
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static const char* toUnixPaths[][2] = static const char* toUnixPaths[][2] =
@ -170,6 +181,135 @@ static bool CheckFileOperations()
res = false; res = false;
} }
// Reset umask
#if defined(_WIN32) && !defined(__CYGWIN__)
// NOTE: Windows doesn't support toggling _S_IREAD.
mode_t fullMask = _S_IWRITE;
#else
// On a normal POSIX platform, we can toggle all permissions.
mode_t fullMask = S_IRWXU | S_IRWXG | S_IRWXO;
#endif
mode_t orig_umask = umask(fullMask);
// Test file permissions without umask
mode_t origPerm, thisPerm;
if (!kwsys::SystemTools::GetPermissions(testNewFile, origPerm))
{
kwsys_ios::cerr
<< "Problem with GetPermissions (1) for: "
<< testNewFile << kwsys_ios::endl;
res = false;
}
if (!kwsys::SystemTools::SetPermissions(testNewFile, 0))
{
kwsys_ios::cerr
<< "Problem with SetPermissions (1) for: "
<< testNewFile << kwsys_ios::endl;
res = false;
}
if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm))
{
kwsys_ios::cerr
<< "Problem with GetPermissions (2) for: "
<< testNewFile << kwsys_ios::endl;
res = false;
}
if ((thisPerm & fullMask) != 0)
{
kwsys_ios::cerr
<< "SetPermissions failed to set permissions (1) for: "
<< testNewFile << ": actual = " << thisPerm << "; expected = "
<< 0 << kwsys_ios::endl;
res = false;
}
// While we're at it, check proper TestFileAccess functionality.
if (kwsys::SystemTools::TestFileAccess(testNewFile,
kwsys::TEST_FILE_WRITE))
{
kwsys_ios::cerr
<< "TestFileAccess incorrectly indicated that this is a writable file:"
<< testNewFile << kwsys_ios::endl;
res = false;
}
if (!kwsys::SystemTools::TestFileAccess(testNewFile,
kwsys::TEST_FILE_OK))
{
kwsys_ios::cerr
<< "TestFileAccess incorrectly indicated that this file does not exist:"
<< testNewFile << kwsys_ios::endl;
res = false;
}
// Test restoring/setting full permissions.
if (!kwsys::SystemTools::SetPermissions(testNewFile, fullMask))
{
kwsys_ios::cerr
<< "Problem with SetPermissions (2) for: "
<< testNewFile << kwsys_ios::endl;
res = false;
}
if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm))
{
kwsys_ios::cerr
<< "Problem with GetPermissions (3) for: "
<< testNewFile << kwsys_ios::endl;
res = false;
}
if ((thisPerm & fullMask) != fullMask)
{
kwsys_ios::cerr
<< "SetPermissions failed to set permissions (2) for: "
<< testNewFile << ": actual = " << thisPerm << "; expected = "
<< fullMask << kwsys_ios::endl;
res = false;
}
// Test setting file permissions while honoring umask
if (!kwsys::SystemTools::SetPermissions(testNewFile, fullMask, true))
{
kwsys_ios::cerr
<< "Problem with SetPermissions (3) for: "
<< testNewFile << kwsys_ios::endl;
res = false;
}
if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm))
{
kwsys_ios::cerr
<< "Problem with GetPermissions (4) for: "
<< testNewFile << kwsys_ios::endl;
res = false;
}
if ((thisPerm & fullMask) != 0)
{
kwsys_ios::cerr
<< "SetPermissions failed to honor umask for: "
<< testNewFile << ": actual = " << thisPerm << "; expected = "
<< 0 << kwsys_ios::endl;
res = false;
}
// Restore umask
umask(orig_umask);
// Restore file permissions
if (!kwsys::SystemTools::SetPermissions(testNewFile, origPerm))
{
kwsys_ios::cerr
<< "Problem with SetPermissions (4) for: "
<< testNewFile << kwsys_ios::endl;
res = false;
}
// Remove the test file
if (!kwsys::SystemTools::RemoveFile(testNewFile)) if (!kwsys::SystemTools::RemoveFile(testNewFile))
{ {
kwsys_ios::cerr kwsys_ios::cerr
@ -271,48 +411,48 @@ static bool CheckStringOperations()
kwsys_ios::cerr kwsys_ios::cerr
<< "Problem with CapitalizedWords " << "Problem with CapitalizedWords "
<< '"' << test << '"' << kwsys_ios::endl; << '"' << test << '"' << kwsys_ios::endl;
res = false; res = false;
} }
test = "Mary Had A Little Lamb."; test = "Mary Had A Little Lamb.";
if (kwsys::SystemTools::UnCapitalizedWords(test) != if (kwsys::SystemTools::UnCapitalizedWords(test) !=
"mary had a little lamb.") "mary had a little lamb.")
{ {
kwsys_ios::cerr kwsys_ios::cerr
<< "Problem with UnCapitalizedWords " << "Problem with UnCapitalizedWords "
<< '"' << test << '"' << kwsys_ios::endl; << '"' << test << '"' << kwsys_ios::endl;
res = false; res = false;
} }
test = "MaryHadTheLittleLamb."; test = "MaryHadTheLittleLamb.";
if (kwsys::SystemTools::AddSpaceBetweenCapitalizedWords(test) != if (kwsys::SystemTools::AddSpaceBetweenCapitalizedWords(test) !=
"Mary Had The Little Lamb.") "Mary Had The Little Lamb.")
{ {
kwsys_ios::cerr kwsys_ios::cerr
<< "Problem with AddSpaceBetweenCapitalizedWords " << "Problem with AddSpaceBetweenCapitalizedWords "
<< '"' << test << '"' << kwsys_ios::endl; << '"' << test << '"' << kwsys_ios::endl;
res = false; res = false;
} }
char * cres = char * cres =
kwsys::SystemTools::AppendStrings("Mary Had A"," Little Lamb."); kwsys::SystemTools::AppendStrings("Mary Had A"," Little Lamb.");
if (strcmp(cres,"Mary Had A Little Lamb.")) if (strcmp(cres,"Mary Had A Little Lamb."))
{ {
kwsys_ios::cerr kwsys_ios::cerr
<< "Problem with AppendStrings " << "Problem with AppendStrings "
<< "\"Mary Had A\" \" Little Lamb.\"" << kwsys_ios::endl; << "\"Mary Had A\" \" Little Lamb.\"" << kwsys_ios::endl;
res = false; res = false;
} }
delete [] cres; delete [] cres;
cres = cres =
kwsys::SystemTools::AppendStrings("Mary Had"," A ","Little Lamb."); kwsys::SystemTools::AppendStrings("Mary Had"," A ","Little Lamb.");
if (strcmp(cres,"Mary Had A Little Lamb.")) if (strcmp(cres,"Mary Had A Little Lamb."))
{ {
kwsys_ios::cerr kwsys_ios::cerr
<< "Problem with AppendStrings " << "Problem with AppendStrings "
<< "\"Mary Had\" \" A \" \"Little Lamb.\"" << kwsys_ios::endl; << "\"Mary Had\" \" A \" \"Little Lamb.\"" << kwsys_ios::endl;
res = false; res = false;
} }
delete [] cres; delete [] cres;
@ -321,28 +461,28 @@ static bool CheckStringOperations()
kwsys_ios::cerr kwsys_ios::cerr
<< "Problem with CountChar " << "Problem with CountChar "
<< "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl; << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
res = false; res = false;
} }
cres = cres =
kwsys::SystemTools::RemoveChars("Mary Had A Little Lamb.","aeiou"); kwsys::SystemTools::RemoveChars("Mary Had A Little Lamb.","aeiou");
if (strcmp(cres,"Mry Hd A Lttl Lmb.")) if (strcmp(cres,"Mry Hd A Lttl Lmb."))
{ {
kwsys_ios::cerr kwsys_ios::cerr
<< "Problem with RemoveChars " << "Problem with RemoveChars "
<< "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl; << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
res = false; res = false;
} }
delete [] cres; delete [] cres;
cres = cres =
kwsys::SystemTools::RemoveCharsButUpperHex("Mary Had A Little Lamb."); kwsys::SystemTools::RemoveCharsButUpperHex("Mary Had A Little Lamb.");
if (strcmp(cres,"A")) if (strcmp(cres,"A"))
{ {
kwsys_ios::cerr kwsys_ios::cerr
<< "Problem with RemoveCharsButUpperHex " << "Problem with RemoveCharsButUpperHex "
<< "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl; << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
res = false; res = false;
} }
delete [] cres; delete [] cres;
@ -354,7 +494,7 @@ static bool CheckStringOperations()
kwsys_ios::cerr kwsys_ios::cerr
<< "Problem with ReplaceChars " << "Problem with ReplaceChars "
<< "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl; << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
res = false; res = false;
} }
delete [] cres2; delete [] cres2;
@ -364,7 +504,7 @@ static bool CheckStringOperations()
kwsys_ios::cerr kwsys_ios::cerr
<< "Problem with StringStartsWith " << "Problem with StringStartsWith "
<< "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl; << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
res = false; res = false;
} }
if (!kwsys::SystemTools::StringEndsWith("Mary Had A Little Lamb.", if (!kwsys::SystemTools::StringEndsWith("Mary Had A Little Lamb.",
@ -373,7 +513,7 @@ static bool CheckStringOperations()
kwsys_ios::cerr kwsys_ios::cerr
<< "Problem with StringEndsWith " << "Problem with StringEndsWith "
<< "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl; << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
res = false; res = false;
} }
cres = kwsys::SystemTools::DuplicateString("Mary Had A Little Lamb."); cres = kwsys::SystemTools::DuplicateString("Mary Had A Little Lamb.");
@ -382,18 +522,18 @@ static bool CheckStringOperations()
kwsys_ios::cerr kwsys_ios::cerr
<< "Problem with DuplicateString " << "Problem with DuplicateString "
<< "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl; << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
res = false; res = false;
} }
delete [] cres; delete [] cres;
test = "Mary Had A Little Lamb."; test = "Mary Had A Little Lamb.";
if (kwsys::SystemTools::CropString(test,13) != if (kwsys::SystemTools::CropString(test,13) !=
"Mary ...Lamb.") "Mary ...Lamb.")
{ {
kwsys_ios::cerr kwsys_ios::cerr
<< "Problem with CropString " << "Problem with CropString "
<< "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl; << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
res = false; res = false;
} }
kwsys_stl::vector<kwsys_stl::string> lines; kwsys_stl::vector<kwsys_stl::string> lines;
@ -515,36 +655,36 @@ static bool CheckStringOperations()
#endif #endif
if (kwsys::SystemTools::ConvertToWindowsOutputPath if (kwsys::SystemTools::ConvertToWindowsOutputPath
("L://Local Mojo/Hex Power Pack/Iffy Voodoo") != ("L://Local Mojo/Hex Power Pack/Iffy Voodoo") !=
"\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"") "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"")
{ {
kwsys_ios::cerr kwsys_ios::cerr
<< "Problem with ConvertToWindowsOutputPath " << "Problem with ConvertToWindowsOutputPath "
<< "\"L://Local Mojo/Hex Power Pack/Iffy Voodoo\"" << "\"L://Local Mojo/Hex Power Pack/Iffy Voodoo\""
<< kwsys_ios::endl; << kwsys_ios::endl;
res = false; res = false;
} }
if (kwsys::SystemTools::ConvertToWindowsOutputPath if (kwsys::SystemTools::ConvertToWindowsOutputPath
("//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo") != ("//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
"\"\\\\grayson\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"") "\"\\\\grayson\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"")
{ {
kwsys_ios::cerr kwsys_ios::cerr
<< "Problem with ConvertToWindowsOutputPath " << "Problem with ConvertToWindowsOutputPath "
<< "\"//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo\"" << "\"//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo\""
<< kwsys_ios::endl; << kwsys_ios::endl;
res = false; res = false;
} }
if (kwsys::SystemTools::ConvertToUnixOutputPath if (kwsys::SystemTools::ConvertToUnixOutputPath
("//Local Mojo/Hex Power Pack/Iffy Voodoo") != ("//Local Mojo/Hex Power Pack/Iffy Voodoo") !=
"//Local\\ Mojo/Hex\\ Power\\ Pack/Iffy\\ Voodoo") "//Local\\ Mojo/Hex\\ Power\\ Pack/Iffy\\ Voodoo")
{ {
kwsys_ios::cerr kwsys_ios::cerr
<< "Problem with ConvertToUnixOutputPath " << "Problem with ConvertToUnixOutputPath "
<< "\"//Local Mojo/Hex Power Pack/Iffy Voodoo\"" << "\"//Local Mojo/Hex Power Pack/Iffy Voodoo\""
<< kwsys_ios::endl; << kwsys_ios::endl;
res = false; res = false;
} }
return res; return res;
@ -672,7 +812,7 @@ int testSystemTools(int, char*[])
for (cc = 0; checkEscapeChars[cc][0]; cc ++ ) for (cc = 0; checkEscapeChars[cc][0]; cc ++ )
{ {
res &= CheckEscapeChars(checkEscapeChars[cc][0], checkEscapeChars[cc][1], res &= CheckEscapeChars(checkEscapeChars[cc][0], checkEscapeChars[cc][1],
*checkEscapeChars[cc][2], checkEscapeChars[cc][3]); *checkEscapeChars[cc][2], checkEscapeChars[cc][3]);
} }