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,14 +1237,12 @@ 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,
// so this will only be true if it is a file
return !isFile || !SystemTools::FileIsDirectory(filename);
}
return false; return false;
} }
return SystemTools::FileExists(kwsys_stl::string(filename), isFile);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool SystemTools::FileExists(const kwsys_stl::string& filename, bool isFile) bool SystemTools::FileExists(const kwsys_stl::string& filename, bool 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>
@ -72,6 +75,24 @@ public:
// 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.
*/ */
@ -292,13 +313,30 @@ 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
@ -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

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