llvm.org GIT mirror llvm / 4a8cbaa
[Support] Add fs::getUmask() function and change fs::setPermissions Summary: This patch changes fs::setPermissions to optionally set permissions while respecting the umask. It also adds the function fs::getUmask() which returns the current umask. Reviewers: jhenderson, rupprecht, aprantl, lhames Reviewed By: jhenderson, rupprecht Subscribers: sanaanajjar231288, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D63583 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364621 91177308-0d34-0410-b5e6-96231b3b80d8 Alex Brachet 3 months ago
4 changed file(s) with 84 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
647647 /// A version for when a file descriptor is already available.
648648 std::error_code status(int FD, file_status &Result);
649649
650 /// Get file creation mode mask of the process.
651 ///
652 /// @returns Mask reported by umask(2)
653 /// @note There is no umask on Windows. This function returns 0 always
654 /// on Windows. This function does not return an error_code because
655 /// umask(2) never fails. It is not thread safe.
656 unsigned getUmask();
657
650658 /// Set file permissions.
651659 ///
652660 /// @param Path File to set permissions on.
653661 /// @param Permissions New file permissions.
662 /// @param RespectUmask If true then Permissions will be changed to respect the
663 /// umask of the current process.
654664 /// @returns errc::success if the permissions were successfully set, otherwise
655665 /// a platform-specific error_code.
656666 /// @note On Windows, all permissions except *_write are ignored. Using any of
657667 /// owner_write, group_write, or all_write will make the file writable.
658668 /// Otherwise, the file will be marked as read-only.
659 std::error_code setPermissions(const Twine &Path, perms Permissions);
669 std::error_code setPermissions(const Twine &Path, perms Permissions,
670 bool RespectUmask = false);
660671
661672 /// Get file permissions.
662673 ///
693693 return fillStatus(StatRet, Status, Result);
694694 }
695695
696 std::error_code setPermissions(const Twine &Path, perms Permissions) {
696 unsigned getUmask() {
697 // Chose arbitary new mask and reset the umask to the old mask.
698 // umask(2) never fails so ignore the return of the second call.
699 unsigned Mask = ::umask(0);
700 (void) ::umask(Mask);
701 return Mask;
702 }
703
704 std::error_code setPermissions(const Twine &Path, perms Permissions,
705 bool RespectUmask) {
697706 SmallString<128> PathStorage;
698707 StringRef P = Path.toNullTerminatedStringRef(PathStorage);
708
709 if (RespectUmask)
710 Permissions = static_cast(Permissions & ~getUmask());
699711
700712 if (::chmod(P.begin(), Permissions))
701713 return std::error_code(errno, std::generic_category());
733733 return getStatus(FileHandle, Result);
734734 }
735735
736 std::error_code setPermissions(const Twine &Path, perms Permissions) {
736 unsigned getUmask() {
737 return 0;
738 }
739
740 std::error_code setPermissions(const Twine &Path, perms Permissions,
741 bool /*RespectUmask*/) {
737742 SmallVector PathUTF16;
738743 if (std::error_code EC = widenPath(Path, PathUTF16))
739744 return EC;
15251525 EXPECT_EQ(TestDirectoryIsLocal, TempFileIsLocal);
15261526 }
15271527
1528 TEST_F(FileSystemTest, getUmask) {
1529 #ifdef _WIN32
1530 EXPECT_EQ(fs::getUmask(), 0U) << "Should always be 0 on Windows.";
1531 #else
1532 unsigned OldMask = ::umask(0022);
1533 unsigned CurrentMask = fs::getUmask();
1534 EXPECT_EQ(CurrentMask, 0022U)
1535 << "getUmask() didn't return previously set umask()";
1536 EXPECT_EQ(::umask(OldMask), 0022) << "getUmask() may have changed umask()";
1537 #endif
1538 }
1539
1540 TEST_F(FileSystemTest, RespectUmask) {
1541 #ifndef _WIN32
1542 unsigned OldMask = ::umask(0022);
1543
1544 int FD;
1545 SmallString<128> TempPath;
1546 ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath));
1547
1548 fs::perms AllRWE = static_cast(0777);
1549
1550 ASSERT_NO_ERROR(fs::setPermissions(TempPath, AllRWE /*RespectUmask=false*/));
1551
1552 ErrorOr Perms = fs::getPermissions(TempPath);
1553 ASSERT_TRUE(!!Perms);
1554 EXPECT_EQ(Perms.get(), AllRWE) << "Should have ignored umask by default";
1555
1556 ASSERT_NO_ERROR(fs::setPermissions(TempPath, AllRWE, /*RespectUmask=*/false));
1557
1558 ErrorOr Perms = fs::getPermissions(TempPath);
1559 ASSERT_TRUE(!!Perms);
1560 EXPECT_EQ(Perms.get(), AllRWE) << "Should have ignored umask";
1561
1562 ASSERT_NO_ERROR(fs::setPermissions(TempPath, AllRWE, /*RespectUmask=*/true));
1563 Perms = fs::getPermissions(TempPath);
1564 ASSERT_TRUE(!!Perms);
1565 EXPECT_EQ(Perms.get(), static_cast(0755))
1566 << "Did not respect umask";
1567
1568 (void)::umask(0057);
1569
1570 ASSERT_NO_ERROR(fs::setPermissions(TempPath, AllRWE, /*RespectUmask=*/true));
1571 Perms = fs::getPermissions(TempPath);
1572 ASSERT_TRUE(!!Perms);
1573 EXPECT_EQ(Perms.get(), static_cast(0720))
1574 << "Did not respect umask";
1575
1576 (void)::umask(OldMask);
1577 (void)::close(FD);
1578 #endif
1579 }
1580
15281581 TEST_F(FileSystemTest, set_current_path) {
15291582 SmallString<128> path;
15301583