* Implement getStatusInfo for getting stat(2) like information
* Implement createTemporaryFile for mkstemp(3) functionality
* Fix isBytecodeFile to accept llvc magic # (compressed) as bytecode.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17654 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/System/Unix/Path.cpp b/lib/System/Unix/Path.cpp
index 4f4d347..c3c6775 100644
--- a/lib/System/Unix/Path.cpp
+++ b/lib/System/Unix/Path.cpp
@@ -164,10 +164,13 @@
 
 bool 
 Path::isBytecodeFile() const {
-  if (readable()) {
-    return hasMagicNumber("llvm");
-  }
-  return false;
+  char buffer[ 4];
+  buffer[0] = 0;
+  std::ifstream f(path.c_str());
+  f.read(buffer, 4);
+  if (f.bad())
+    ThrowErrno("can't read file signature");
+  return 0 == memcmp(buffer,"llvc",4) || 0 == memcmp(buffer,"llvm",4);
 }
 
 bool
@@ -220,6 +223,19 @@
   return path.substr(pos+1);
 }
 
+void
+Path::getStatusInfo(StatusInfo& info) const {
+  struct stat buf;
+  if (0 != stat(path.c_str(), &buf)) {
+    ThrowErrno(std::string("Can't get status: ")+path);
+  }
+  info.fileSize = buf.st_size;
+  info.modTime.fromPosixTime(buf.st_mtime);
+  info.mode = buf.st_mode;
+  info.user = buf.st_uid;
+  info.group = buf.st_gid;
+}
+
 bool
 Path::setDirectory(const std::string& a_path) {
   if (a_path.size() == 0)
@@ -379,13 +395,31 @@
   // Create the file
   int fd = ::creat(path.c_str(), S_IRUSR | S_IWUSR);
   if (fd < 0)
-    ThrowErrno(std::string(path.c_str()) + ": Can't create file");
+    ThrowErrno(path + ": Can't create file");
   ::close(fd);
 
   return true;
 }
 
 bool
+Path::createTemporaryFile() {
+  // Make sure we're dealing with a file
+  if (!isFile()) return false;
+
+  // Append the filename filler
+  char pathname[MAXPATHLEN];
+  path.copy(pathname,MAXPATHLEN);
+  strcat(pathname,"XXXXXX");
+  int fd = ::mkstemp(pathname);
+  if (fd < 0) {
+    ThrowErrno(path + ": Can't create temporary file");
+  }
+  path = pathname;
+  ::close(fd);
+  return true;
+}
+
+bool
 Path::destroyDirectory(bool remove_contents) {
   // Make sure we're dealing with a directory
   if (!isDirectory()) return false;
diff --git a/lib/System/Unix/Path.inc b/lib/System/Unix/Path.inc
index 4f4d347..c3c6775 100644
--- a/lib/System/Unix/Path.inc
+++ b/lib/System/Unix/Path.inc
@@ -164,10 +164,13 @@
 
 bool 
 Path::isBytecodeFile() const {
-  if (readable()) {
-    return hasMagicNumber("llvm");
-  }
-  return false;
+  char buffer[ 4];
+  buffer[0] = 0;
+  std::ifstream f(path.c_str());
+  f.read(buffer, 4);
+  if (f.bad())
+    ThrowErrno("can't read file signature");
+  return 0 == memcmp(buffer,"llvc",4) || 0 == memcmp(buffer,"llvm",4);
 }
 
 bool
@@ -220,6 +223,19 @@
   return path.substr(pos+1);
 }
 
+void
+Path::getStatusInfo(StatusInfo& info) const {
+  struct stat buf;
+  if (0 != stat(path.c_str(), &buf)) {
+    ThrowErrno(std::string("Can't get status: ")+path);
+  }
+  info.fileSize = buf.st_size;
+  info.modTime.fromPosixTime(buf.st_mtime);
+  info.mode = buf.st_mode;
+  info.user = buf.st_uid;
+  info.group = buf.st_gid;
+}
+
 bool
 Path::setDirectory(const std::string& a_path) {
   if (a_path.size() == 0)
@@ -379,13 +395,31 @@
   // Create the file
   int fd = ::creat(path.c_str(), S_IRUSR | S_IWUSR);
   if (fd < 0)
-    ThrowErrno(std::string(path.c_str()) + ": Can't create file");
+    ThrowErrno(path + ": Can't create file");
   ::close(fd);
 
   return true;
 }
 
 bool
+Path::createTemporaryFile() {
+  // Make sure we're dealing with a file
+  if (!isFile()) return false;
+
+  // Append the filename filler
+  char pathname[MAXPATHLEN];
+  path.copy(pathname,MAXPATHLEN);
+  strcat(pathname,"XXXXXX");
+  int fd = ::mkstemp(pathname);
+  if (fd < 0) {
+    ThrowErrno(path + ": Can't create temporary file");
+  }
+  path = pathname;
+  ::close(fd);
+  return true;
+}
+
+bool
 Path::destroyDirectory(bool remove_contents) {
   // Make sure we're dealing with a directory
   if (!isDirectory()) return false;