// FileStatus.cxx #include "dataset_util/FileStatus.h" #include #include #include #include using std::string; using std::ostream; typedef FileStatus::size_type size_type; typedef FileStatus::Time Time; //********************************************************************** // Local definitions. //********************************************************************** class FileStatusImp { public: // File name. std::string name; // Return from status check. int istat; // Posix status struct. struct stat sbuf; // Constructor. FileStatusImp(string iname) : name(iname) { update(); } // Update. int update() { istat = stat(name.c_str(), &sbuf); return istat; } }; //********************************************************************** // Member functions. //********************************************************************** // Constructor from name. FileStatus::FileStatus(string name) : m_pimp(new FileStatusImp(name)) { update(); } //********************************************************************** // Constructor from directory plus name. FileStatus::FileStatus(string dir, string name) : m_pimp(new FileStatusImp(dir + "/" + name)) { update(); } //********************************************************************** // Copy constructor. FileStatus::FileStatus(const FileStatus& rhs) : m_pimp(new FileStatusImp(*rhs.m_pimp)) { } //********************************************************************** // Assignment. FileStatus& FileStatus::operator=(const FileStatus& rhs) { if ( &rhs == this ) return *this; delete m_pimp; m_pimp = new FileStatusImp(*rhs.m_pimp); return *this; } //********************************************************************** // Destructor. FileStatus::~FileStatus() { delete m_pimp; } //********************************************************************** // Update. int FileStatus::update() { return m_pimp->update(); } //********************************************************************** // Name. string FileStatus::name() const { return m_pimp->name; } //********************************************************************** // Exists. bool FileStatus::exists() const { return m_pimp->istat == 0; } //********************************************************************** // Regular. bool FileStatus::is_regular() const { return exists() && S_ISREG(m_pimp->sbuf.st_mode); } //********************************************************************** // Directory. bool FileStatus::is_directory() const { return exists() && S_ISDIR(m_pimp->sbuf.st_mode); } //********************************************************************** // Special. bool FileStatus::is_special() const { return exists() && !is_regular() && !is_directory(); } //********************************************************************** // Readable. bool FileStatus::is_readable() const { return exists() && bool(m_pimp->sbuf.st_mode & S_IRUSR); } //********************************************************************** // Writeable. bool FileStatus::is_writeable() const { return exists() && bool(m_pimp->sbuf.st_mode & S_IWUSR); } //********************************************************************** // Executable. bool FileStatus::is_executable() const { return exists() && bool(m_pimp->sbuf.st_mode & S_IXUSR); } //********************************************************************** // World writeable. bool FileStatus::is_world_writeable() const { return exists() && bool(m_pimp->sbuf.st_mode & S_IWOTH); } //********************************************************************** // Size. size_type FileStatus::size() const { return m_pimp->sbuf.st_size; } //********************************************************************** // Modification time. Time FileStatus::modtime() const { return m_pimp->sbuf.st_mtime; } //********************************************************************** // Access time. Time FileStatus::acctime() const { return m_pimp->sbuf.st_atime; } //********************************************************************** // Symlink?. bool FileStatus::is_symlink() const { int islink = false; struct stat slbuf; int istat = lstat(m_pimp->name.c_str(), &slbuf); if ( istat == 0 ) { dev_t dev1 = m_pimp->sbuf.st_dev; ino_t ino1 = m_pimp->sbuf.st_ino; dev_t dev2 = slbuf.st_dev; ino_t ino2 = slbuf.st_ino; islink = dev1!=dev2 || ino1!=ino2; } return islink; } //********************************************************************** // Free functions. //********************************************************************** // Output stream. ostream& operator<<(ostream& lhs, const FileStatus& rhs) { lhs << "File " << rhs.name(); if ( rhs.exists() ) { if ( rhs.is_regular() ) { lhs << " is regular"; } else if ( rhs.is_directory() ) { lhs << " is a directory"; } else if ( rhs.is_special() ) { lhs << " is special"; } else { assert(false); } lhs << " ("; if ( rhs.is_readable() ) { lhs << "R"; } else { lhs << "-"; } if ( rhs.is_writeable() ) { lhs << "W"; } else { lhs << "-"; } if ( rhs.is_executable() ) { lhs << "X"; } else { lhs << "-"; } lhs << ")"; if ( rhs.is_regular() ) { lhs << " and holds " << rhs.size() << " bytes"; } } else { lhs << " does not exist"; } return lhs; } //********************************************************************** // Equality. bool operator==(const FileStatus& lhs, const FileStatus& rhs) { return lhs.name() == rhs.name(); } //**********************************************************************