[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

llvm-svn: 364621
diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
index 280624e..761d183 100644
--- a/llvm/lib/Support/Unix/Path.inc
+++ b/llvm/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();