[llvm-commits] CVS: llvm/lib/System/Unix/Path.inc Signals.inc

Reid Spencer reid at x10sys.com
Thu Mar 29 12:06:34 PDT 2007



Changes in directory llvm/lib/System/Unix:

Path.inc updated: 1.60 -> 1.61
Signals.inc updated: 1.15 -> 1.16
---
Log message:

For PR789: http://llvm.org/PR789 :
Make the sys::Path::getFileStatus function more efficient by having it
return a pointer to the FileStatus structure rather than copy it. Adjust
uses of the function accordingly. Also, fix some memory issues in sys::Path.


---
Diffs of the changes:  (+39 -34)

 Path.inc    |   67 +++++++++++++++++++++++++++++++-----------------------------
 Signals.inc |    6 +++--
 2 files changed, 39 insertions(+), 34 deletions(-)


Index: llvm/lib/System/Unix/Path.inc
diff -u llvm/lib/System/Unix/Path.inc:1.60 llvm/lib/System/Unix/Path.inc:1.61
--- llvm/lib/System/Unix/Path.inc:1.60	Thu Mar 29 12:00:31 2007
+++ llvm/lib/System/Unix/Path.inc	Thu Mar 29 14:05:44 2007
@@ -333,9 +333,10 @@
 Path::canExecute() const {
   if (0 != access(path.c_str(), R_OK | X_OK ))
     return false;
-  struct stat st;
-  int r = stat(path.c_str(), &st);
-  if (r != 0 || !S_ISREG(st.st_mode))
+  if (const FileStatus *fs = getFileStatus(true, 0)) {
+    if (!S_ISREG(fs->mode))
+      return false;
+  } else
     return false;
   return true;
 }
@@ -362,12 +363,14 @@
   return path.substr(pos+1);
 }
 
-bool
-Path::getFileStatus(FileStatus &info, bool update, std::string *ErrStr) const {
+const FileStatus*
+Path::getFileStatus(bool update, std::string *ErrStr) const {
   if (status == 0 || update) {
     struct stat buf;
-    if (0 != stat(path.c_str(), &buf))
-      return MakeErrMsg(ErrStr, path + ": can't get status of file");
+    if (0 != stat(path.c_str(), &buf)) {
+      MakeErrMsg(ErrStr, path + ": can't get status of file");
+      return 0;
+    }
     if (status == 0)
       status = new FileStatus;
     status->fileSize = buf.st_size;
@@ -379,8 +382,7 @@
     status->isDir  = S_ISDIR(buf.st_mode);
     status->isFile = S_ISREG(buf.st_mode);
   }
-  info = *status;
-  return false;
+  return status;
 }
 
 static bool AddPermissionBits(const Path &File, int bits) {
@@ -392,12 +394,12 @@
   umask(mask);            // Restore the umask.
 
   // Get the file's current mode.
-  FileStatus Stat;
-  if (File.getFileStatus(Stat)) return false;
-
-  // Change the file to have whichever permissions bits from 'bits'
-  // that the umask would not disable.
-  if ((chmod(File.c_str(), (Stat.getMode() | (bits & ~mask)))) == -1)
+  if (const FileStatus *fs = File.getFileStatus()) {
+    // Change the file to have whichever permissions bits from 'bits'
+    // that the umask would not disable.
+    if ((chmod(File.c_str(), (fs->getMode() | (bits & ~mask)))) == -1)
+      return false;
+  } else 
     return false;
 
   return true;
@@ -593,24 +595,25 @@
 bool
 Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const {
   FileStatus Status;
-  if (getFileStatus(Status, ErrStr))
-    return true;
+  if (const FileStatus *Status = getFileStatus(false, ErrStr)) {
+    // Note: this check catches strange situations. In all cases, LLVM should 
+    // only be involved in the creation and deletion of regular files.  This 
+    // check ensures that what we're trying to erase is a regular file. It 
+    // effectively prevents LLVM from erasing things like /dev/null, any block 
+    // special file, or other things that aren't "regular" files. 
+    if (Status->isFile) {
+      if (unlink(path.c_str()) != 0)
+        return MakeErrMsg(ErrStr, path + ": can't destroy file");
+      return false;
+    }
     
-  // Note: this check catches strange situations. In all cases, LLVM should only
-  // be involved in the creation and deletion of regular files.  This check 
-  // ensures that what we're trying to erase is a regular file. It effectively
-  // prevents LLVM from erasing things like /dev/null, any block special file,
-  // or other things that aren't "regular" files. 
-  if (Status.isFile) {
-    if (unlink(path.c_str()) != 0)
-      return MakeErrMsg(ErrStr, path + ": can't destroy file");
-    return false;
-  }
-  
-  if (!Status.isDir) {
-    if (ErrStr) *ErrStr = "not a file or directory";
+    if (!Status->isDir) {
+      if (ErrStr) *ErrStr = "not a file or directory";
+      return true;
+    }
+  } else
     return true;
-  }
+
   if (remove_contents) {
     // Recursively descend the directory to remove its contents.
     std::string cmd = "/bin/rm -rf " + path;
@@ -629,7 +632,7 @@
     
   if (rmdir(pathname) != 0)
     return MakeErrMsg(ErrStr, 
-      std::string(pathname) + ": can't destroy directory");
+      std::string(pathname) + ": can't erase directory");
   return false;
 }
 


Index: llvm/lib/System/Unix/Signals.inc
diff -u llvm/lib/System/Unix/Signals.inc:1.15 llvm/lib/System/Unix/Signals.inc:1.16
--- llvm/lib/System/Unix/Signals.inc:1.15	Fri Aug 25 16:37:17 2006
+++ llvm/lib/System/Unix/Signals.inc	Thu Mar 29 14:05:44 2007
@@ -168,8 +168,10 @@
 // RemoveDirectoryOnSignal - The public API
 bool sys::RemoveDirectoryOnSignal(const sys::Path& path, std::string* ErrMsg) {
   // Not a directory?
-  sys::FileStatus Status;
-  if (path.getFileStatus(Status) || !Status.isDir) {
+  const sys::FileStatus *Status = path.getFileStatus(false, ErrMsg);
+  if (!Status)
+    return true;
+  if (!Status->isDir) {
     if (ErrMsg)
       *ErrMsg = path.toString() + " is not a directory";
     return true;






More information about the llvm-commits mailing list