From: Reid Spencer Date: Tue, 9 Nov 2004 20:26:31 +0000 (+0000) Subject: * Implement getStatusInfo for getting stat(2) like information X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=9195f37c5f16ad59f3b4acb27ac3731715dd42c6;p=oota-llvm.git * 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/include/llvm/System/Path.h b/include/llvm/System/Path.h index 7f59d601352..77a5add2fc6 100644 --- a/include/llvm/System/Path.h +++ b/include/llvm/System/Path.h @@ -16,6 +16,7 @@ #include #include +#include "llvm/System/TimeValue.h" namespace llvm { namespace sys { @@ -306,6 +307,24 @@ namespace sys { /// @brief Get the base name of the path std::string getBasename() const; + /// This structure provides basic file system information about a file. + /// The structure is filled in by the getStatusInfo method. + /// @brief File status structure + struct StatusInfo { + StatusInfo() : modTime(0,0) { fileSize=0; mode=0; user=0; group=0; } + size_t fileSize; ///< Size of the file in bytes + TimeValue modTime; ///< Time of file's modification + uint64_t mode; ///< Mode of the file, if applicable + uint64_t user; ///< User ID of owner, if applicable + uint64_t group; ///< Group ID of owner, if applicable + }; + + /// This function returns status information about the file. + /// @returns nothing + /// @throws std::string if an error occurs. + /// @brief Get file status. + void getStatusInfo(StatusInfo& stat) const; + /// @returns a c string containing the path name. /// @brief Returns the path as a C string. const char* const c_str() const { return path.c_str(); } @@ -425,6 +444,17 @@ namespace sys { /// @brief Create the file this Path refers to. bool createFile(); + /// This is like createFile except that it creates a temporary file. A + /// unique temporary file name is generated based on the contents of + /// \p this before the call. The new name is assigned to \p this and the + /// file is created. Note that this will both change the Path object + /// *and* create the corresponding file. The path of \p this will have + /// six characters added to it (per mkstemp(3)) that ensure the file + /// name is unique. + /// @throws std::string if there is an error + /// @brief Create a temporary file + bool createTemporaryFile(); + /// This method attempts to destroy the directory named by the last in /// the Path name. If \p remove_contents is false, an attempt will be /// made to remove just the directory that this Path object refers to diff --git a/lib/System/Unix/Path.cpp b/lib/System/Unix/Path.cpp index 4f4d347f092..c3c6775968c 100644 --- a/lib/System/Unix/Path.cpp +++ b/lib/System/Unix/Path.cpp @@ -164,10 +164,13 @@ bool Path::hasMagicNumber(const std::string &Magic) const { 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 @@ Path::getLast() const { 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,12 +395,30 @@ Path::createFile() { // 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 diff --git a/lib/System/Unix/Path.inc b/lib/System/Unix/Path.inc index 4f4d347f092..c3c6775968c 100644 --- a/lib/System/Unix/Path.inc +++ b/lib/System/Unix/Path.inc @@ -164,10 +164,13 @@ bool Path::hasMagicNumber(const std::string &Magic) const { 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 @@ Path::getLast() const { 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,12 +395,30 @@ Path::createFile() { // 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