From 566fdf4a2a898bc9b1bd4b5e1cd110b8e94d2fcc Mon Sep 17 00:00:00 2001 From: James Henderson Date: Thu, 16 Mar 2017 11:22:09 +0000 Subject: [Support] Add support for getting file system permissions on Windows and implement sys::fs::set/getPermissions to work with them This change adds support for functions to set and get file permissions, in a similar manner to the C++17 permissions() function in . The setter uses chmod on Unix systems and SetFileAttributes on Windows, setting the permissions as passed in. The getter simply uses the existing status() function. Prior to this change, status() would always return an unknown value for the permissions on a Windows file, making it impossible to test the new function on Windows. I have therefore added support for this as well. On Linux, prior to this change, the permissions included the file type, which should actually be accessed via a different member of the file_status class. Note that on Windows, only the *_write permission bits have any affect - if any are set, the file is writable, and if not, the file is read-only. This is in common with what MSDN describes for their behaviour of std::filesystem::permissions(), and also what boost::filesystem does. The motivation behind this change is so that we can easily test behaviour on read-only files in LLVM unit tests, but I am sure that others may find it useful in some situations. Reviewers: zturner, amccarth, aaron.ballman Differential Revision: https://reviews.llvm.org/D30736 llvm-svn: 297945 --- llvm/unittests/Support/Path.cpp | 171 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) (limited to 'llvm/unittests/Support/Path.cpp') diff --git a/llvm/unittests/Support/Path.cpp b/llvm/unittests/Support/Path.cpp index b79586b9946..8068b320306 100644 --- a/llvm/unittests/Support/Path.cpp +++ b/llvm/unittests/Support/Path.cpp @@ -1335,4 +1335,175 @@ TEST_F(FileSystemTest, set_current_path) { ASSERT_EQ(D1, D2) << "D1: " << TestDirectory << "\nD2: " << path; } +TEST_F(FileSystemTest, permissions) { + int FD; + SmallString<64> TempPath; + ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath)); + FileRemover Cleanup(TempPath); + + // Make sure it exists. + ASSERT_TRUE(fs::exists(Twine(TempPath))); + + auto CheckPermissions = [&](fs::perms Expected) { + ErrorOr Actual = fs::getPermissions(TempPath); + return Actual && *Actual == Expected; + }; + + std::error_code NoError; + EXPECT_EQ(fs::setPermissions(TempPath, fs::all_all), NoError); + EXPECT_TRUE(CheckPermissions(fs::all_all)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::all_read | fs::all_exe), NoError); + EXPECT_TRUE(CheckPermissions(fs::all_read | fs::all_exe)); + +#if defined(LLVM_ON_WIN32) + fs::perms ReadOnly = fs::all_read | fs::all_exe; + EXPECT_EQ(fs::setPermissions(TempPath, fs::no_perms), NoError); + EXPECT_TRUE(CheckPermissions(ReadOnly)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_read), NoError); + EXPECT_TRUE(CheckPermissions(ReadOnly)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_write), NoError); + EXPECT_TRUE(CheckPermissions(fs::all_all)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_exe), NoError); + EXPECT_TRUE(CheckPermissions(ReadOnly)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_all), NoError); + EXPECT_TRUE(CheckPermissions(fs::all_all)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::group_read), NoError); + EXPECT_TRUE(CheckPermissions(ReadOnly)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::group_write), NoError); + EXPECT_TRUE(CheckPermissions(fs::all_all)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::group_exe), NoError); + EXPECT_TRUE(CheckPermissions(ReadOnly)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::group_all), NoError); + EXPECT_TRUE(CheckPermissions(fs::all_all)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::others_read), NoError); + EXPECT_TRUE(CheckPermissions(ReadOnly)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::others_write), NoError); + EXPECT_TRUE(CheckPermissions(fs::all_all)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::others_exe), NoError); + EXPECT_TRUE(CheckPermissions(ReadOnly)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::others_all), NoError); + EXPECT_TRUE(CheckPermissions(fs::all_all)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::all_read), NoError); + EXPECT_TRUE(CheckPermissions(ReadOnly)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::all_write), NoError); + EXPECT_TRUE(CheckPermissions(fs::all_all)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::all_exe), NoError); + EXPECT_TRUE(CheckPermissions(ReadOnly)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::set_uid_on_exe), NoError); + EXPECT_TRUE(CheckPermissions(ReadOnly)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::set_gid_on_exe), NoError); + EXPECT_TRUE(CheckPermissions(ReadOnly)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::sticky_bit), NoError); + EXPECT_TRUE(CheckPermissions(ReadOnly)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::set_uid_on_exe | + fs::set_gid_on_exe | + fs::sticky_bit), + NoError); + EXPECT_TRUE(CheckPermissions(ReadOnly)); + + EXPECT_EQ(fs::setPermissions(TempPath, ReadOnly | fs::set_uid_on_exe | + fs::set_gid_on_exe | + fs::sticky_bit), + NoError); + EXPECT_TRUE(CheckPermissions(ReadOnly)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::all_perms), NoError); + EXPECT_TRUE(CheckPermissions(fs::all_all)); +#else + EXPECT_EQ(fs::setPermissions(TempPath, fs::no_perms), NoError); + EXPECT_TRUE(CheckPermissions(fs::no_perms)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_read), NoError); + EXPECT_TRUE(CheckPermissions(fs::owner_read)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_write), NoError); + EXPECT_TRUE(CheckPermissions(fs::owner_write)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_exe), NoError); + EXPECT_TRUE(CheckPermissions(fs::owner_exe)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_all), NoError); + EXPECT_TRUE(CheckPermissions(fs::owner_all)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::group_read), NoError); + EXPECT_TRUE(CheckPermissions(fs::group_read)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::group_write), NoError); + EXPECT_TRUE(CheckPermissions(fs::group_write)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::group_exe), NoError); + EXPECT_TRUE(CheckPermissions(fs::group_exe)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::group_all), NoError); + EXPECT_TRUE(CheckPermissions(fs::group_all)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::others_read), NoError); + EXPECT_TRUE(CheckPermissions(fs::others_read)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::others_write), NoError); + EXPECT_TRUE(CheckPermissions(fs::others_write)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::others_exe), NoError); + EXPECT_TRUE(CheckPermissions(fs::others_exe)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::others_all), NoError); + EXPECT_TRUE(CheckPermissions(fs::others_all)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::all_read), NoError); + EXPECT_TRUE(CheckPermissions(fs::all_read)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::all_write), NoError); + EXPECT_TRUE(CheckPermissions(fs::all_write)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::all_exe), NoError); + EXPECT_TRUE(CheckPermissions(fs::all_exe)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::set_uid_on_exe), NoError); + EXPECT_TRUE(CheckPermissions(fs::set_uid_on_exe)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::set_gid_on_exe), NoError); + EXPECT_TRUE(CheckPermissions(fs::set_gid_on_exe)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::sticky_bit), NoError); + EXPECT_TRUE(CheckPermissions(fs::sticky_bit)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::set_uid_on_exe | + fs::set_gid_on_exe | + fs::sticky_bit), + NoError); + EXPECT_TRUE(CheckPermissions(fs::set_uid_on_exe | fs::set_gid_on_exe | + fs::sticky_bit)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::all_read | fs::set_uid_on_exe | + fs::set_gid_on_exe | + fs::sticky_bit), + NoError); + EXPECT_TRUE(CheckPermissions(fs::all_read | fs::set_uid_on_exe | + fs::set_gid_on_exe | fs::sticky_bit)); + + EXPECT_EQ(fs::setPermissions(TempPath, fs::all_perms), NoError); + EXPECT_TRUE(CheckPermissions(fs::all_perms)); +#endif +} + } // anonymous namespace -- cgit v1.2.3