if(): add operators IS_READABLE, IS_WRITABLE and IS_EXECUTABLE.
Offers possibility to check for file or directory permissions.
This commit is contained in:
parent
fdf6435427
commit
337bc5662c
@ -178,6 +178,47 @@ File Operations
|
||||
|
||||
False if the given path is an empty string.
|
||||
|
||||
.. warning::
|
||||
To check the readability of a file, use preferably ``if(IS_READABLE)``
|
||||
because this test will evolve to check file existence only in a future
|
||||
release.
|
||||
|
||||
.. signature:: if(IS_READABLE <path-to-file-or-directory>)
|
||||
|
||||
.. versionadded:: 3.29
|
||||
|
||||
True if the named file or directory is readable. Behavior
|
||||
is well-defined only for explicit full paths (a leading ``~/`` is not
|
||||
expanded as a home directory and is considered a relative path).
|
||||
Resolves symbolic links, i.e. if the named file or directory is a
|
||||
symbolic link, returns true if the target of the symbolic link is readable.
|
||||
|
||||
False if the given path is an empty string.
|
||||
|
||||
.. signature:: if(IS_WRITABLE <path-to-file-or-directory>)
|
||||
|
||||
.. versionadded:: 3.29
|
||||
|
||||
True if the named file or directory is writable. Behavior
|
||||
is well-defined only for explicit full paths (a leading ``~/`` is not
|
||||
expanded as a home directory and is considered a relative path).
|
||||
Resolves symbolic links, i.e. if the named file or directory is a
|
||||
symbolic link, returns true if the target of the symbolic link is writable.
|
||||
|
||||
False if the given path is an empty string.
|
||||
|
||||
.. signature:: if(IS_EXECUTABLE <path-to-file-or-directory>)
|
||||
|
||||
.. versionadded:: 3.29
|
||||
|
||||
True if the named file or directory is executable. Behavior
|
||||
is well-defined only for explicit full paths (a leading ``~/`` is not
|
||||
expanded as a home directory and is considered a relative path).
|
||||
Resolves symbolic links, i.e. if the named file or directory is a
|
||||
symbolic link, returns true if the target of the symbolic link is executable.
|
||||
|
||||
False if the given path is an empty string.
|
||||
|
||||
.. signature:: if(<file1> IS_NEWER_THAN <file2>)
|
||||
:target: IS_NEWER_THAN
|
||||
|
||||
|
5
Help/release/dev/if-check-file-permissions.rst
Normal file
5
Help/release/dev/if-check-file-permissions.rst
Normal file
@ -0,0 +1,5 @@
|
||||
if-check-file-permissions
|
||||
-------------------------
|
||||
|
||||
* The :command:`if` command gained new tests ``IS_READABLE``, ``IS_WRITABLE``
|
||||
and ``IS_EXECUTABLE`` to check file or directory permissions.
|
@ -33,6 +33,9 @@ auto const keyCOMMAND = "COMMAND"_s;
|
||||
auto const keyDEFINED = "DEFINED"_s;
|
||||
auto const keyEQUAL = "EQUAL"_s;
|
||||
auto const keyEXISTS = "EXISTS"_s;
|
||||
auto const keyIS_READABLE = "IS_READABLE"_s;
|
||||
auto const keyIS_WRITABLE = "IS_WRITABLE"_s;
|
||||
auto const keyIS_EXECUTABLE = "IS_EXECUTABLE"_s;
|
||||
auto const keyGREATER = "GREATER"_s;
|
||||
auto const keyGREATER_EQUAL = "GREATER_EQUAL"_s;
|
||||
auto const keyIN_LIST = "IN_LIST"_s;
|
||||
@ -568,6 +571,24 @@ bool cmConditionEvaluator::HandleLevel1(cmArgumentList& newArgs, std::string&,
|
||||
newArgs.ReduceOneArg(cmSystemTools::FileExists(args.next->GetValue()),
|
||||
args);
|
||||
}
|
||||
// check if a file is readable
|
||||
else if (this->IsKeyword(keyIS_READABLE, *args.current)) {
|
||||
newArgs.ReduceOneArg(cmSystemTools::TestFileAccess(
|
||||
args.next->GetValue(), cmsys::TEST_FILE_READ),
|
||||
args);
|
||||
}
|
||||
// check if a file is writable
|
||||
else if (this->IsKeyword(keyIS_WRITABLE, *args.current)) {
|
||||
newArgs.ReduceOneArg(cmSystemTools::TestFileAccess(
|
||||
args.next->GetValue(), cmsys::TEST_FILE_WRITE),
|
||||
args);
|
||||
}
|
||||
// check if a file is executable
|
||||
else if (this->IsKeyword(keyIS_EXECUTABLE, *args.current)) {
|
||||
newArgs.ReduceOneArg(cmSystemTools::TestFileAccess(
|
||||
args.next->GetValue(), cmsys::TEST_FILE_EXECUTE),
|
||||
args);
|
||||
}
|
||||
// does a directory with this name exist
|
||||
else if (this->IsKeyword(keyIS_DIRECTORY, *args.current)) {
|
||||
newArgs.ReduceOneArg(
|
||||
|
@ -535,7 +535,7 @@ add_RunCMake_test(function)
|
||||
add_RunCMake_test(block)
|
||||
add_RunCMake_test(get_filename_component)
|
||||
add_RunCMake_test(get_property)
|
||||
add_RunCMake_test(if)
|
||||
add_RunCMake_test(if -DMSYS=${MSYS})
|
||||
add_RunCMake_test(include)
|
||||
add_RunCMake_test(include_directories)
|
||||
add_RunCMake_test(include_guard)
|
||||
|
153
Tests/RunCMake/if/FilePermissions.cmake
Normal file
153
Tests/RunCMake/if/FilePermissions.cmake
Normal file
@ -0,0 +1,153 @@
|
||||
|
||||
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/readable.txt"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/writable.txt"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/executable.txt")
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/readable.txt" "foo")
|
||||
file(CHMOD "${CMAKE_CURRENT_BINARY_DIR}/readable.txt" PERMISSIONS OWNER_READ GROUP_READ WORLD_READ)
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/writable.txt" "foo")
|
||||
file(CHMOD "${CMAKE_CURRENT_BINARY_DIR}/writable.txt" PERMISSIONS OWNER_WRITE GROUP_WRITE WORLD_WRITE)
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/executable.txt" "foo")
|
||||
file(CHMOD "${CMAKE_CURRENT_BINARY_DIR}/executable.txt" PERMISSIONS OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
|
||||
|
||||
if(NOT WIN32)
|
||||
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/readable-dir"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/writable-dir"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/executable-dir")
|
||||
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/readable-dir")
|
||||
file(CHMOD "${CMAKE_CURRENT_BINARY_DIR}/readable-dir" PERMISSIONS OWNER_READ GROUP_READ WORLD_READ)
|
||||
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/writable-dir")
|
||||
file(CHMOD "${CMAKE_CURRENT_BINARY_DIR}/writable-dir" PERMISSIONS OWNER_WRITE GROUP_WRITE WORLD_WRITE)
|
||||
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/executable-dir")
|
||||
file(CHMOD "${CMAKE_CURRENT_BINARY_DIR}/executable-dir" PERMISSIONS OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# files are always readable and executable
|
||||
# directories are always, readable, writable and executable
|
||||
if(NOT IS_READABLE "${CMAKE_CURRENT_BINARY_DIR}/readable.txt"
|
||||
OR IS_WRITABLE "${CMAKE_CURRENT_BINARY_DIR}/readable.txt")
|
||||
message(FATAL_ERROR "checks on \"${CMAKE_CURRENT_BINARY_DIR}/readable.txt\" failed")
|
||||
endif()
|
||||
|
||||
if(NOT IS_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/executable.txt"
|
||||
OR IS_WRITABLE "${CMAKE_CURRENT_BINARY_DIR}/executable.txt")
|
||||
message(FATAL_ERROR "checks on \"${CMAKE_CURRENT_BINARY_DIR}/executable.txt\" failed")
|
||||
endif()
|
||||
else()
|
||||
if(NOT IS_READABLE "${CMAKE_CURRENT_BINARY_DIR}/readable.txt"
|
||||
OR IS_WRITABLE "${CMAKE_CURRENT_BINARY_DIR}/readable.txt"
|
||||
OR IS_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/readable.txt")
|
||||
message(FATAL_ERROR "checks on \"${CMAKE_CURRENT_BINARY_DIR}/readable.txt\" failed")
|
||||
endif()
|
||||
|
||||
if(NOT IS_WRITABLE "${CMAKE_CURRENT_BINARY_DIR}/writable.txt"
|
||||
OR IS_READABLE "${CMAKE_CURRENT_BINARY_DIR}/writable.txt"
|
||||
OR IS_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/writable.txt")
|
||||
message(FATAL_ERROR "checks on \"${CMAKE_CURRENT_BINARY_DIR}/writable.txt\" failed")
|
||||
endif()
|
||||
|
||||
if(NOT IS_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/executable.txt"
|
||||
OR IS_READABLE "${CMAKE_CURRENT_BINARY_DIR}/executable.txt"
|
||||
OR IS_WRITABLE "${CMAKE_CURRENT_BINARY_DIR}/executable.txt")
|
||||
message(FATAL_ERROR "checks on \"${CMAKE_CURRENT_BINARY_DIR}/executable.txt\" failed")
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT IS_READABLE "${CMAKE_CURRENT_BINARY_DIR}/readable-dir"
|
||||
OR IS_WRITABLE "${CMAKE_CURRENT_BINARY_DIR}/readable-dir"
|
||||
OR IS_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/readable-dir")
|
||||
message(FATAL_ERROR "checks on \"${CMAKE_CURRENT_BINARY_DIR}/readable-dir\" failed")
|
||||
endif()
|
||||
|
||||
if(NOT IS_WRITABLE "${CMAKE_CURRENT_BINARY_DIR}/writable-dir"
|
||||
OR IS_READABLE "${CMAKE_CURRENT_BINARY_DIR}/writable-dir"
|
||||
OR IS_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/writable-dir")
|
||||
message(FATAL_ERROR "checks on \"${CMAKE_CURRENT_BINARY_DIR}/writable-dir\" failed")
|
||||
endif()
|
||||
|
||||
if(NOT IS_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/executable-dir"
|
||||
OR IS_READABLE "${CMAKE_CURRENT_BINARY_DIR}/executable-dir"
|
||||
OR IS_WRITABLE "${CMAKE_CURRENT_BINARY_DIR}/executable-dir")
|
||||
message(FATAL_ERROR "checks on \"${CMAKE_CURRENT_BINARY_DIR}/executable.txt\" failed")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
#
|
||||
# Check that file permissions are on the real file, not the symbolic link
|
||||
#
|
||||
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/link-to-readable.txt"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/link-to-writable.txt"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/link-to-executable.txt"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/link-to-readable-dir"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/link-to-writable-dir"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/link-to-executable-dir")
|
||||
|
||||
file(CREATE_LINK "${CMAKE_CURRENT_BINARY_DIR}/readable.txt"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/link-to-readable.txt"
|
||||
SYMBOLIC)
|
||||
|
||||
file(CREATE_LINK "${CMAKE_CURRENT_BINARY_DIR}/writable.txt"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/link-to-writable.txt"
|
||||
SYMBOLIC)
|
||||
|
||||
file(CREATE_LINK "${CMAKE_CURRENT_BINARY_DIR}/executable.txt"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/link-to-executable.txt"
|
||||
SYMBOLIC)
|
||||
|
||||
|
||||
file(CREATE_LINK "${CMAKE_CURRENT_BINARY_DIR}/readable-dir"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/link-to-readable-dir"
|
||||
SYMBOLIC)
|
||||
|
||||
file(CREATE_LINK "${CMAKE_CURRENT_BINARY_DIR}/writable-dir"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/link-to-writable-dir"
|
||||
SYMBOLIC)
|
||||
|
||||
file(CREATE_LINK "${CMAKE_CURRENT_BINARY_DIR}/executable-dir"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/link-to-executable-dir"
|
||||
SYMBOLIC)
|
||||
|
||||
if(NOT IS_READABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-readable.txt"
|
||||
OR IS_WRITABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-readable.txt"
|
||||
OR IS_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-readable.txt")
|
||||
message(FATAL_ERROR "checks on \"${CMAKE_CURRENT_BINARY_DIR}/link-to-readable.txt\" failed")
|
||||
endif()
|
||||
|
||||
if(NOT IS_WRITABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-writable.txt"
|
||||
OR IS_READABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-writable.txt"
|
||||
OR IS_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-writable.txt")
|
||||
message(FATAL_ERROR "checks on \"${CMAKE_CURRENT_BINARY_DIR}/link-to-writable.txt\" failed")
|
||||
endif()
|
||||
|
||||
if(NOT IS_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-executable.txt"
|
||||
OR IS_READABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-executable.txt"
|
||||
OR IS_WRITABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-executable.txt")
|
||||
message(FATAL_ERROR "checks on \"${CMAKE_CURRENT_BINARY_DIR}/link-to-executable.txt\" failed")
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT IS_READABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-readable-dir"
|
||||
OR IS_WRITABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-readable-dir"
|
||||
OR IS_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-readable-dir")
|
||||
message(FATAL_ERROR "checks on \"${CMAKE_CURRENT_BINARY_DIR}/link-to-readable-dir\" failed")
|
||||
endif()
|
||||
|
||||
if(NOT IS_WRITABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-writable-dir"
|
||||
OR IS_READABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-writable-dir"
|
||||
OR IS_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-writable-dir")
|
||||
message(FATAL_ERROR "checks on \"${CMAKE_CURRENT_BINARY_DIR}/link-to-writable-dir\" failed")
|
||||
endif()
|
||||
|
||||
if(NOT IS_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-executable-dir"
|
||||
OR IS_READABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-executable-dir"
|
||||
OR IS_WRITABLE "${CMAKE_CURRENT_BINARY_DIR}/link-to-executable-dir")
|
||||
message(FATAL_ERROR "checks on \"${CMAKE_CURRENT_BINARY_DIR}/link-to-executable-dir\" failed")
|
||||
endif()
|
||||
endif()
|
@ -2,6 +2,23 @@ include(RunCMake)
|
||||
|
||||
run_cmake(InvalidArgument1)
|
||||
run_cmake(exists)
|
||||
if(NOT MSYS)
|
||||
# permissions and symbolic links are broken on MSYS
|
||||
unset(uid)
|
||||
unset(status)
|
||||
if(UNIX)
|
||||
set(ID "id")
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND EXISTS "/usr/xpg4/bin/id")
|
||||
set (ID "/usr/xpg4/bin/id")
|
||||
endif()
|
||||
# if real user is root, tests are irrelevant
|
||||
execute_process(COMMAND ${ID} -u $ENV{USER} OUTPUT_VARIABLE uid ERROR_QUIET
|
||||
RESULT_VARIABLE status OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
endif()
|
||||
if(NOT status AND NOT uid STREQUAL "0")
|
||||
run_cmake(FilePermissions)
|
||||
endif()
|
||||
endif()
|
||||
run_cmake(IsDirectory)
|
||||
run_cmake(IsDirectoryLong)
|
||||
run_cmake(duplicate-deep-else)
|
||||
|
Loading…
Reference in New Issue
Block a user