aboutsummaryrefslogtreecommitdiffstats
path: root/lib/System/Unix
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2007-04-07 18:52:17 +0000
committerReid Spencer <rspencer@reidspencer.com>2007-04-07 18:52:17 +0000
commit2ae9d11b7c0fd54e0b5298fb4fcf17b6ee9d5c91 (patch)
tree47499784611ea34bf3d97785c62b6eebf4a7057d /lib/System/Unix
parente9ed4452bce4f5a7f8005d7ebd649a20c22ef268 (diff)
downloadexternal_llvm-2ae9d11b7c0fd54e0b5298fb4fcf17b6ee9d5c91.zip
external_llvm-2ae9d11b7c0fd54e0b5298fb4fcf17b6ee9d5c91.tar.gz
external_llvm-2ae9d11b7c0fd54e0b5298fb4fcf17b6ee9d5c91.tar.bz2
For PR1291:
Implement the PathWithStatus class and its use throughout lib/System. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35742 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/System/Unix')
-rw-r--r--lib/System/Unix/Path.inc89
-rw-r--r--lib/System/Unix/Signals.inc12
2 files changed, 54 insertions, 47 deletions
diff --git a/lib/System/Unix/Path.inc b/lib/System/Unix/Path.inc
index 6ceffcd..53906d9 100644
--- a/lib/System/Unix/Path.inc
+++ b/lib/System/Unix/Path.inc
@@ -333,10 +333,10 @@ bool
Path::canExecute() const {
if (0 != access(path.c_str(), R_OK | X_OK ))
return false;
- if (const FileStatus *fs = getFileStatus(true, 0)) {
- if (!S_ISREG(fs->mode))
- return false;
- } else
+ struct stat buf;
+ if (0 != stat(path.c_str(), &buf))
+ return false;
+ if (!S_ISREG(buf.st_mode))
return false;
return true;
}
@@ -363,26 +363,25 @@ Path::getLast() const {
return path.substr(pos+1);
}
-const FileStatus*
-Path::getFileStatus(bool update, std::string *ErrStr) const {
- if (status == 0 || update) {
+const FileStatus *
+PathWithStatus::getFileStatus(bool update, std::string *ErrStr) const {
+ if (!fsIsValid || update) {
struct stat buf;
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;
- status->modTime.fromEpochTime(buf.st_mtime);
- status->mode = buf.st_mode;
- status->user = buf.st_uid;
- status->group = buf.st_gid;
- status->uniqueID = uint64_t(buf.st_ino);
- status->isDir = S_ISDIR(buf.st_mode);
- status->isFile = S_ISREG(buf.st_mode);
+ status.fileSize = buf.st_size;
+ status.modTime.fromEpochTime(buf.st_mtime);
+ status.mode = buf.st_mode;
+ status.user = buf.st_uid;
+ status.group = buf.st_gid;
+ status.uniqueID = uint64_t(buf.st_ino);
+ status.isDir = S_ISDIR(buf.st_mode);
+ status.isFile = S_ISREG(buf.st_mode);
+ fsIsValid = true;
}
- return status;
+ return &status;
}
static bool AddPermissionBits(const Path &File, int bits) {
@@ -394,14 +393,13 @@ static bool AddPermissionBits(const Path &File, int bits) {
umask(mask); // Restore the umask.
// Get the file's current mode.
- 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
+ struct stat buf;
+ if (0 != stat(File.toString().c_str(), &buf))
return false;
-
+ // Change the file to have whichever permissions bits from 'bits'
+ // that the umask would not disable.
+ if ((chmod(File.c_str(), (buf.st_mode | (bits & ~mask)))) == -1)
+ return false;
return true;
}
@@ -594,25 +592,28 @@ Path::createTemporaryFileOnDisk(bool reuse_current, std::string* ErrMsg) {
bool
Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const {
- FileStatus Status;
- 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;
- }
-
- if (!Status->isDir) {
- if (ErrStr) *ErrStr = "not a file or directory";
- return true;
- }
- } else
+ // Get the status so we can determin if its a file or directory
+ struct stat buf;
+ if (0 != stat(path.c_str(), &buf)) {
+ MakeErrMsg(ErrStr, path + ": can't get status of file");
return true;
+ }
+
+ // 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 (S_ISREG(buf.st_mode)) {
+ if (unlink(path.c_str()) != 0)
+ return MakeErrMsg(ErrStr, path + ": can't destroy file");
+ return false;
+ }
+
+ if (!S_ISDIR(buf.st_mode)) {
+ if (ErrStr) *ErrStr = "not a file or directory";
+ return true;
+ }
if (remove_contents) {
// Recursively descend the directory to remove its contents.
@@ -644,7 +645,7 @@ Path::renamePathOnDisk(const Path& newName, std::string* ErrMsg) {
return false;
}
-bool
+bool
Path::setStatusInfoOnDisk(const FileStatus &si, std::string *ErrStr) const {
struct utimbuf utb;
utb.actime = si.modTime.toPosixTime();
diff --git a/lib/System/Unix/Signals.inc b/lib/System/Unix/Signals.inc
index a471b95..d1493a2 100644
--- a/lib/System/Unix/Signals.inc
+++ b/lib/System/Unix/Signals.inc
@@ -21,6 +21,9 @@
#if HAVE_SIGNAL_H
#include <signal.h>
#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
using namespace llvm;
namespace {
@@ -168,10 +171,13 @@ bool sys::RemoveFileOnSignal(const sys::Path &Filename, std::string* ErrMsg) {
// RemoveDirectoryOnSignal - The public API
bool sys::RemoveDirectoryOnSignal(const sys::Path& path, std::string* ErrMsg) {
// Not a directory?
- const sys::FileStatus *Status = path.getFileStatus(false, ErrMsg);
- if (!Status)
+ struct stat buf;
+ if (0 != stat(path.c_str(), &buf)) {
+ MakeErrMsg(ErrMsg, path.toString() + ": can't get status of file");
return true;
- if (!Status->isDir) {
+ }
+
+ if (!S_ISDIR(buf.st_mode)) {
if (ErrMsg)
*ErrMsg = path.toString() + " is not a directory";
return true;