Page MenuHomePhabricator

D63583.diff
No OneTemporary

File Metadata

Created
Sat, Aug 24, 9:47 PM

D63583.diff

Index: llvm/trunk/include/llvm/Support/FileSystem.h
===================================================================
--- llvm/trunk/include/llvm/Support/FileSystem.h
+++ llvm/trunk/include/llvm/Support/FileSystem.h
@@ -648,16 +648,27 @@
/// A version for when a file descriptor is already available.
std::error_code status(int FD, file_status &Result);
+/// Get file creation mode mask of the process.
+///
+/// @returns Mask reported by umask(2)
+/// @note There is no umask on Windows. This function returns 0 always
+/// on Windows. This function does not return an error_code because
+/// umask(2) never fails. It is not thread safe.
+unsigned getUmask();
+
/// Set file permissions.
///
/// @param Path File to set permissions on.
/// @param Permissions New file permissions.
+/// @param RespectUmask If true then Permissions will be changed to respect the
+/// umask of the current process.
/// @returns errc::success if the permissions were successfully set, otherwise
/// a platform-specific error_code.
/// @note On Windows, all permissions except *_write are ignored. Using any of
/// owner_write, group_write, or all_write will make the file writable.
/// Otherwise, the file will be marked as read-only.
-std::error_code setPermissions(const Twine &Path, perms Permissions);
+std::error_code setPermissions(const Twine &Path, perms Permissions,
+ bool RespectUmask = false);
/// Get file permissions.
///
Index: llvm/trunk/lib/Support/Unix/Path.inc
===================================================================
--- llvm/trunk/lib/Support/Unix/Path.inc
+++ llvm/trunk/lib/Support/Unix/Path.inc
@@ -694,10 +694,22 @@
return fillStatus(StatRet, Status, Result);
}
-std::error_code setPermissions(const Twine &Path, perms Permissions) {
+unsigned getUmask() {
+ // Chose arbitary new mask and reset the umask to the old mask.
+ // umask(2) never fails so ignore the return of the second call.
+ unsigned Mask = ::umask(0);
+ (void) ::umask(Mask);
+ return Mask;
+}
+
+std::error_code setPermissions(const Twine &Path, perms Permissions,
+ bool RespectUmask) {
SmallString<128> PathStorage;
StringRef P = Path.toNullTerminatedStringRef(PathStorage);
+ if (RespectUmask)
+ Permissions = static_cast<perms>(Permissions & ~getUmask());
+
if (::chmod(P.begin(), Permissions))
return std::error_code(errno, std::generic_category());
return std::error_code();
Index: llvm/trunk/lib/Support/Windows/Path.inc
===================================================================
--- llvm/trunk/lib/Support/Windows/Path.inc
+++ llvm/trunk/lib/Support/Windows/Path.inc
@@ -734,7 +734,12 @@
return getStatus(FileHandle, Result);
}
-std::error_code setPermissions(const Twine &Path, perms Permissions) {
+unsigned getUmask() {
+ return 0;
+}
+
+std::error_code setPermissions(const Twine &Path, perms Permissions,
+ bool /*RespectUmask*/) {
SmallVector<wchar_t, 128> PathUTF16;
if (std::error_code EC = widenPath(Path, PathUTF16))
return EC;
Index: llvm/trunk/unittests/Support/Path.cpp
===================================================================
--- llvm/trunk/unittests/Support/Path.cpp
+++ llvm/trunk/unittests/Support/Path.cpp
@@ -1526,6 +1526,59 @@
EXPECT_EQ(TestDirectoryIsLocal, TempFileIsLocal);
}
+TEST_F(FileSystemTest, getUmask) {
+#ifdef _WIN32
+ EXPECT_EQ(fs::getUmask(), 0U) << "Should always be 0 on Windows.";
+#else
+ unsigned OldMask = ::umask(0022);
+ unsigned CurrentMask = fs::getUmask();
+ EXPECT_EQ(CurrentMask, 0022U)
+ << "getUmask() didn't return previously set umask()";
+ EXPECT_EQ(::umask(OldMask), 0022) << "getUmask() may have changed umask()";
+#endif
+}
+
+TEST_F(FileSystemTest, RespectUmask) {
+#ifndef _WIN32
+ unsigned OldMask = ::umask(0022);
+
+ int FD;
+ SmallString<128> TempPath;
+ ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath));
+
+ fs::perms AllRWE = static_cast<fs::perms>(0777);
+
+ ASSERT_NO_ERROR(fs::setPermissions(TempPath, AllRWE /*RespectUmask=false*/));
+
+ ErrorOr<fs::perms> Perms = fs::getPermissions(TempPath);
+ ASSERT_TRUE(!!Perms);
+ EXPECT_EQ(Perms.get(), AllRWE) << "Should have ignored umask by default";
+
+ ASSERT_NO_ERROR(fs::setPermissions(TempPath, AllRWE, /*RespectUmask=*/false));
+
+ ErrorOr<fs::perms> Perms = fs::getPermissions(TempPath);
+ ASSERT_TRUE(!!Perms);
+ EXPECT_EQ(Perms.get(), AllRWE) << "Should have ignored umask";
+
+ ASSERT_NO_ERROR(fs::setPermissions(TempPath, AllRWE, /*RespectUmask=*/true));
+ Perms = fs::getPermissions(TempPath);
+ ASSERT_TRUE(!!Perms);
+ EXPECT_EQ(Perms.get(), static_cast<fs::perms>(0755))
+ << "Did not respect umask";
+
+ (void)::umask(0057);
+
+ ASSERT_NO_ERROR(fs::setPermissions(TempPath, AllRWE, /*RespectUmask=*/true));
+ Perms = fs::getPermissions(TempPath);
+ ASSERT_TRUE(!!Perms);
+ EXPECT_EQ(Perms.get(), static_cast<fs::perms>(0720))
+ << "Did not respect umask";
+
+ (void)::umask(OldMask);
+ (void)::close(FD);
+#endif
+}
+
TEST_F(FileSystemTest, set_current_path) {
SmallString<128> path;

Event Timeline