Commit cdaf522c authored by James Johnston's avatar James Johnston
Browse files

SystemTools: Add honor_umask parameter to SetPermissions.

If honor_umask is set, the umask is queried and applied to the
given permissions when calling SetPermissions.

Change-Id: I302231a2ae7f0c4610eb47fdb256fa02934ecd8c
parent 8970cd56
...@@ -68,6 +68,10 @@ ...@@ -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>
...@@ -4780,21 +4784,35 @@ bool SystemTools::GetPermissions(const kwsys_stl::string& file, mode_t& mode) ...@@ -4780,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 )
......
...@@ -758,17 +758,27 @@ public: ...@@ -758,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
......
...@@ -30,6 +30,17 @@ ...@@ -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() ...@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment