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; _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits