Added the MakeFileExecutable() method.  This method takes a filename and
gives it execute access while respecting the user's umask.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8324 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/Support/FileUtilities.h b/include/Support/FileUtilities.h
index 2c8eba3..4770494 100644
--- a/include/Support/FileUtilities.h
+++ b/include/Support/FileUtilities.h
@@ -36,4 +36,19 @@
 ///
 std::string getUniqueFilename(const std::string &FilenameBase);
 
+///
+/// Method: MakeFileExecutable()
+///
+/// Description:
+///	This method turns on whatever access attributes are needed to make the
+///	specified file executable.
+///
+/// Return value:
+///	True  - The operation succeeded.
+///	False - The operation failed.
+///
+/// Notes:
+///	In case of failure, the file's access attributes are unspecified.
+///
+bool MakeFileExecutable (const std::string & Filename);
 #endif
diff --git a/include/llvm/Support/FileUtilities.h b/include/llvm/Support/FileUtilities.h
index 2c8eba3..4770494 100644
--- a/include/llvm/Support/FileUtilities.h
+++ b/include/llvm/Support/FileUtilities.h
@@ -36,4 +36,19 @@
 ///
 std::string getUniqueFilename(const std::string &FilenameBase);
 
+///
+/// Method: MakeFileExecutable()
+///
+/// Description:
+///	This method turns on whatever access attributes are needed to make the
+///	specified file executable.
+///
+/// Return value:
+///	True  - The operation succeeded.
+///	False - The operation failed.
+///
+/// Notes:
+///	In case of failure, the file's access attributes are unspecified.
+///
+bool MakeFileExecutable (const std::string & Filename);
 #endif
diff --git a/lib/Support/FileUtilities.cpp b/lib/Support/FileUtilities.cpp
index 3e4c270..01d7ca2 100644
--- a/lib/Support/FileUtilities.cpp
+++ b/lib/Support/FileUtilities.cpp
@@ -7,6 +7,8 @@
 
 #include "Support/FileUtilities.h"
 #include "Config/unistd.h"
+#include "Config/sys/stat.h"
+#include "Config/sys/types.h"
 #include <fstream>
 #include <iostream>
 #include <cstdio>
@@ -90,3 +92,51 @@
   delete[] FNBuffer;
   return Result;
 }
+
+///
+/// Method: MakeFileExecutable ()
+///
+/// Description:
+///	This method makes the specified filename executable by giving it
+///	execute permission.
+///
+///	For the UNIX version of this method, we turn on all of the read and
+///	execute bits and then turn off anything specified in the umask.  This
+///	should help ensure that access to the file remains at the level that
+///	the user desires.
+///
+bool
+MakeFileExecutable (const std::string & Filename)
+{
+  // Permissions masking value of the user
+  mode_t mask;
+
+  // Permissions currently enabled on the file
+  struct stat fstat;
+
+  //
+  // Grab the umask value from the operating system.  We want to use it when
+  // changing the file's permissions.
+  //
+  // Note:
+  //  Umask() is one of those annoying system calls.  You have to call it
+  //  to get the current value and then set it back.
+  //
+  mask = umask (0x777);
+  umask (mask);
+
+  //
+  // Go fetch the file's current permission bits.  We want to *add* execute
+  // access to the file.
+  //
+  if ((stat (Filename.c_str(), &fstat)) == -1)
+  {
+    return false;
+  }
+
+  // Make the script executable...
+  chmod(Filename.c_str(), (fstat.st_mode | (0111 & ~mask)));
+
+  return true;
+}
+
diff --git a/support/lib/Support/FileUtilities.cpp b/support/lib/Support/FileUtilities.cpp
index 3e4c270..01d7ca2 100644
--- a/support/lib/Support/FileUtilities.cpp
+++ b/support/lib/Support/FileUtilities.cpp
@@ -7,6 +7,8 @@
 
 #include "Support/FileUtilities.h"
 #include "Config/unistd.h"
+#include "Config/sys/stat.h"
+#include "Config/sys/types.h"
 #include <fstream>
 #include <iostream>
 #include <cstdio>
@@ -90,3 +92,51 @@
   delete[] FNBuffer;
   return Result;
 }
+
+///
+/// Method: MakeFileExecutable ()
+///
+/// Description:
+///	This method makes the specified filename executable by giving it
+///	execute permission.
+///
+///	For the UNIX version of this method, we turn on all of the read and
+///	execute bits and then turn off anything specified in the umask.  This
+///	should help ensure that access to the file remains at the level that
+///	the user desires.
+///
+bool
+MakeFileExecutable (const std::string & Filename)
+{
+  // Permissions masking value of the user
+  mode_t mask;
+
+  // Permissions currently enabled on the file
+  struct stat fstat;
+
+  //
+  // Grab the umask value from the operating system.  We want to use it when
+  // changing the file's permissions.
+  //
+  // Note:
+  //  Umask() is one of those annoying system calls.  You have to call it
+  //  to get the current value and then set it back.
+  //
+  mask = umask (0x777);
+  umask (mask);
+
+  //
+  // Go fetch the file's current permission bits.  We want to *add* execute
+  // access to the file.
+  //
+  if ((stat (Filename.c_str(), &fstat)) == -1)
+  {
+    return false;
+  }
+
+  // Make the script executable...
+  chmod(Filename.c_str(), (fstat.st_mode | (0111 & ~mask)));
+
+  return true;
+}
+