diff options
-rw-r--r-- | src/corelib/io/qfilesystemengine_unix.cpp | 102 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemmetadata_p.h | 9 | ||||
-rw-r--r-- | tests/manual/filetest/main.cpp | 55 |
3 files changed, 143 insertions, 23 deletions
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 1774ef609b..7f043582e8 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -157,10 +157,9 @@ static bool isPackage(const QFileSystemMetaData &data, const QFileSystemEntry &e } #endif -#if !QT_CONFIG(futimens) && (QT_CONFIG(futimes)) namespace { namespace GetFileTimes { - +#if !QT_CONFIG(futimens) && (QT_CONFIG(futimes)) template <typename T> static inline typename QtPrivate::QEnableIf<(&T::st_atim, &T::st_mtim, true)>::Type get(const T *p, struct timeval *access, struct timeval *modification) { @@ -190,11 +189,86 @@ static inline typename QtPrivate::QEnableIf<(&T::st_atimensec, &T::st_mtimensec, modification->tv_sec = p->st_mtime; modification->tv_usec = p->st_mtimensec / 1000; } +#endif +qint64 timespecToMSecs(const timespec &spec) +{ + return (qint64(spec.tv_sec) * 1000) + (spec.tv_nsec / 1000000); } -} + +// fallback set +Q_DECL_UNUSED qint64 atime(const QT_STATBUF &statBuffer, ulong) { return qint64(statBuffer.st_atime) * 1000; } +Q_DECL_UNUSED qint64 birthtime(const QT_STATBUF &, ulong) { return Q_INT64_C(0); } +Q_DECL_UNUSED qint64 ctime(const QT_STATBUF &statBuffer, ulong) { return qint64(statBuffer.st_ctime) * 1000; } +Q_DECL_UNUSED qint64 mtime(const QT_STATBUF &statBuffer, ulong) { return qint64(statBuffer.st_mtime) * 1000; } + +// Xtim, POSIX.1-2008 +template <typename T> +Q_DECL_UNUSED static typename std::enable_if<(&T::st_atim, true), qint64>::type +atime(const T &statBuffer, int) +{ return timespecToMSecs(statBuffer.st_atim); } + +template <typename T> +Q_DECL_UNUSED static typename std::enable_if<(&T::st_birthtim, true), qint64>::type +birthtime(const T &statBuffer, int) +{ return timespecToMSecs(statBuffer.st_birthtim); } + +template <typename T> +Q_DECL_UNUSED static typename std::enable_if<(&T::st_ctim, true), qint64>::type +ctime(const T &statBuffer, int) +{ return timespecToMSecs(statBuffer.st_ctim); } + +template <typename T> +Q_DECL_UNUSED static typename std::enable_if<(&T::st_mtim, true), qint64>::type +mtime(const T &statBuffer, int) +{ return timespecToMSecs(statBuffer.st_mtim); } + +#ifndef st_mtimespec +// Xtimespec +template <typename T> +Q_DECL_UNUSED static typename std::enable_if<(&T::st_atimespec, true), qint64>::type +atime(const T &statBuffer, int) +{ return timespecToMSecs(statBuffer.st_atimespec); } + +template <typename T> +Q_DECL_UNUSED static typename std::enable_if<(&T::st_birthtimespec, true), qint64>::type +birthtime(const T &statBuffer, int) +{ return timespecToMSecs(statBuffer.st_birthtimespec); } + +template <typename T> +Q_DECL_UNUSED static typename std::enable_if<(&T::st_ctimespec, true), qint64>::type +ctime(const T &statBuffer, int) +{ return timespecToMSecs(statBuffer.st_ctimespec); } + +template <typename T> +Q_DECL_UNUSED static typename std::enable_if<(&T::st_mtimespec, true), qint64>::type +mtime(const T &statBuffer, int) +{ return timespecToMSecs(statBuffer.st_mtimespec); } #endif +// Xtimensec +template <typename T> +Q_DECL_UNUSED static typename std::enable_if<(&T::st_atimensec, true), qint64>::type +atime(const T &statBuffer, int) +{ return statBuffer.st_atime * Q_INT64_C(1000) + statBuffer.st_atimensec / 1000000; } + +template <typename T> +Q_DECL_UNUSED static typename std::enable_if<(&T::st_birthtimensec, true), qint64>::type +birthtime(const T &statBuffer, int) +{ return statBuffer.st_birthtime * Q_INT64_C(1000) + statBuffer.st_birthtimensec / 1000000; } + +template <typename T> +Q_DECL_UNUSED static typename std::enable_if<(&T::st_ctimensec, true), qint64>::type +ctime(const T &statBuffer, int) +{ return statBuffer.st_ctime * Q_INT64_C(1000) + statBuffer.st_ctimensec / 1000000; } + +template <typename T> +Q_DECL_UNUSED static typename std::enable_if<(&T::st_mtimensec, true), qint64>::type +mtime(const T &statBuffer, int) +{ return statBuffer.st_mtime * Q_INT64_C(1000) + statBuffer.st_mtimensec / 1000000; } +} +} + //static bool QFileSystemEngine::fillMetaData(int fd, QFileSystemMetaData &data) { @@ -229,13 +303,6 @@ static void fillStat64fromStat32(struct stat64 *statBuf64, const struct stat &st } #endif -#if _POSIX_VERSION >= 200809L -static qint64 timespecToMSecs(const timespec &spec) -{ - return (qint64(spec.tv_sec) * 1000) + (spec.tv_nsec / 1000000); -} -#endif - void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) { // Permissions @@ -281,16 +348,11 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) #endif // Times - birthTime_ = 0; -#if _POSIX_VERSION >= 200809L - modificationTime_ = timespecToMSecs(statBuffer.st_mtim); - metadataChangeTime_ = timespecToMSecs(statBuffer.st_ctim); - accessTime_ = timespecToMSecs(statBuffer.st_atim); -#else - modificationTime_ = qint64(statBuffer.st_mtime) * 1000; - metadataChangeTime_ = qint64(statBuffer.st_ctime) * 1000; - accessTime_ = qint64(statBuffer.st_atime) * 1000; -#endif + accessTime_ = GetFileTimes::atime(statBuffer, 0); + birthTime_ = GetFileTimes::birthtime(statBuffer, 0); + metadataChangeTime_ = GetFileTimes::ctime(statBuffer, 0); + modificationTime_ = GetFileTimes::mtime(statBuffer, 0); + userId_ = statBuffer.st_uid; groupId_ = statBuffer.st_gid; } diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 3eeb26247f..c4e1312c1d 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -293,9 +293,12 @@ inline QDateTime QFileSystemMetaData::fileTime(QAbstractFileEngine::FileTime tim #if defined(Q_OS_UNIX) inline QDateTime QFileSystemMetaData::birthTime() const { return birthTime_ ? QDateTime::fromMSecsSinceEpoch(birthTime_) : QDateTime(); } -inline QDateTime QFileSystemMetaData::metadataChangeTime() const { return QDateTime::fromMSecsSinceEpoch(metadataChangeTime_); } -inline QDateTime QFileSystemMetaData::modificationTime() const { return QDateTime::fromMSecsSinceEpoch(modificationTime_); } -inline QDateTime QFileSystemMetaData::accessTime() const { return QDateTime::fromMSecsSinceEpoch(accessTime_); } +inline QDateTime QFileSystemMetaData::metadataChangeTime() const +{ return metadataChangeTime_ ? QDateTime::fromMSecsSinceEpoch(metadataChangeTime_) : QDateTime(); } +inline QDateTime QFileSystemMetaData::modificationTime() const +{ return modificationTime_ ? QDateTime::fromMSecsSinceEpoch(modificationTime_) : QDateTime(); } +inline QDateTime QFileSystemMetaData::accessTime() const +{ return accessTime_ ? QDateTime::fromMSecsSinceEpoch(accessTime_) : QDateTime(); } inline uint QFileSystemMetaData::userId() const { return userId_; } inline uint QFileSystemMetaData::groupId() const { return groupId_; } diff --git a/tests/manual/filetest/main.cpp b/tests/manual/filetest/main.cpp index 396fcdb24b..c278fd87ce 100644 --- a/tests/manual/filetest/main.cpp +++ b/tests/manual/filetest/main.cpp @@ -26,6 +26,7 @@ ** ****************************************************************************/ +#include <QDateTime> #include <QDebug> #include <QCoreApplication> #include <QFileInfo> @@ -40,12 +41,25 @@ static const char usage1[] = "Usage: "; static const char usage2[] =" [KEYWORD] [ARGUMENTS]\n\n" "Keywords: ls FILES list file information\n" +" stat FILES print detailed file information\n" " mv SOURCE TARGET rename files using QFile::rename\n" " cp SOURCE TARGET copy files using QFile::copy\n" " rm FILE remove file using QFile::remove\n" " rmr DIR remove directory recursively\n" " using QDir::removeRecursively\n"; +std::ostream &operator<<(std::ostream &o, const QString &str) +{ + return o << qPrintable(str); +} + +std::ostream &operator<<(std::ostream &o, const QDateTime &dt) +{ + if (dt.isValid()) + return o << dt.toString(Qt::ISODateWithMs); + return o << '-'; +} + static inline std::string permissions(QFile::Permissions permissions) { std::string result(10, '-'); @@ -102,6 +116,44 @@ static int ls(int argCount, char **args) return 0; } +static int stat(int argCount, char **args) +{ + for (int i = 0 ; i < argCount; ++i) { + const QFileInfo fi(QFile::decodeName(args[i])); + std::cout << "Name:\t" << fi.fileName() << std::endl; + std::cout << "Path:\t" << QDir::toNativeSeparators(fi.path()) + << " (" << QDir::toNativeSeparators(fi.absolutePath()) << ')' << std::endl; + std::cout << "Size:\t" << fi.size() + << "\tType: " + << (fi.isSymLink() && !fi.exists() ? "Broken symlink" : + !fi.exists() ? "Non-existent" : + fi.isSymLink() ? "Symlink to " : "") + << (!fi.exists() ? "" : + fi.isFile() ? "Regular file" : + fi.isDir() ? "Directory" : "Special node") + << std::endl; + if (fi.isSymLink()) + std::cout << "Target:\t" << fi.symLinkTarget() << std::endl; + std::cout << "Attrs: " + << (fi.isReadable() ? " readable" : "") + << (fi.isWritable() ? " writable" : "") + << (fi.isExecutable() ? " executable" : "") + << (fi.isHidden() ? " hidden" : "") + << (fi.isNativePath() ? " nativepath" : "") + << (fi.isRoot() ? " root" : "") + << (fi.isBundle() ? " bundle" : "") + << std::endl; + std::cout << "Mode:\t" << permissions(fi) << std::endl; + std::cout << "Owner:\t" << fi.owner() << " (" << fi.ownerId() + << ")\tGroup:\t" << fi.group() << " (" << fi.groupId() << ')' << std::endl; + std::cout << "Access:\t" << fi.lastRead() << std::endl; + std::cout << "Birth:\t" << fi.birthTime() << std::endl; + std::cout << "Change:\t" << fi.metadataChangeTime() << std::endl; + std::cout << "Modified: " << fi.lastModified() << std::endl; + } + return 0; +} + static int mv(const char *sourceFileName, const char *targetFileName) { QFile sourceFile(QString::fromLocal8Bit(sourceFileName)); @@ -155,6 +207,9 @@ int main(int argc, char *argv[]) if (argc >= 3 && !qstrcmp(argv[1], "ls")) return ls(argc -2, argv + 2); + if (argc >= 3 && !qstrcmp(argv[1], "stat")) + return stat(argc -2, argv + 2); + if (argc == 4 && !qstrcmp(argv[1], "mv")) return mv(argv[2], argv[3]); |