From db433bdf65e011e64be51948e79abc02034dddbf Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 2 Jul 2017 10:28:39 -0700 Subject: [PATCH] Move platform-specific code from QFSFileEngine to QFileSystemEngine Change-Id: I8d96dea9955d4c749b99fffd14cd9395174ba005 Reviewed-by: Lars Knoll --- src/corelib/io/qfilesystemengine_p.h | 8 ++ src/corelib/io/qfilesystemengine_unix.cpp | 106 ++++++++++++++++++++++ src/corelib/io/qfilesystemengine_win.cpp | 58 ++++++++++++ src/corelib/io/qfsfileengine_unix.cpp | 102 +-------------------- src/corelib/io/qfsfileengine_win.cpp | 66 +------------- 5 files changed, 178 insertions(+), 162 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index f625f4dcd8..a3c96ebd78 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -93,6 +93,8 @@ public: #if defined(Q_OS_UNIX) static bool fillMetaData(int fd, QFileSystemMetaData &data); // what = PosixStatFlags static QByteArray id(int fd); + static bool setFileTime(int fd, const QDateTime &newDate, + QAbstractFileEngine::FileTime whatTime, QSystemError &error); static bool setPermissions(int fd, QFile::Permissions permissions, QSystemError &error, QFileSystemMetaData *data = nullptr); #endif @@ -106,6 +108,8 @@ public: static bool fillPermissions(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what); static QByteArray id(HANDLE fHandle); + static bool setFileTime(HANDLE fHandle, const QDateTime &newDate, + QAbstractFileEngine::FileTime whatTime, QSystemError &error); static QString owner(const QFileSystemEntry &entry, QAbstractFileEngine::FileOwner own); static QString nativeAbsoluteFilePath(const QString &path); #endif @@ -127,6 +131,10 @@ public: static bool setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QSystemError &error, QFileSystemMetaData *data = 0); + // unused, therefore not implemented + static bool setFileTime(const QFileSystemEntry &entry, const QDateTime &newDate, + QAbstractFileEngine::FileTime whatTime, QSystemError &error); + static bool setCurrentPath(const QFileSystemEntry &entry); static QFileSystemEntry currentPath(); diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 79b015938c..89250c52f3 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -157,6 +157,44 @@ static bool isPackage(const QFileSystemMetaData &data, const QFileSystemEntry &e } #endif +#if !QT_CONFIG(futimens) && (QT_CONFIG(futimes) || QT_CONFIG(futimesat)) +namespace { +namespace GetFileTimes { + +template +static inline typename QtPrivate::QEnableIf<(&T::st_atim, &T::st_mtim, true)>::Type get(const T *p, struct timeval *access, struct timeval *modification) +{ + access->tv_sec = p->st_atim.tv_sec; + access->tv_usec = p->st_atim.tv_nsec / 1000; + + modification->tv_sec = p->st_mtim.tv_sec; + modification->tv_usec = p->st_mtim.tv_nsec / 1000; +} + +template +static inline typename QtPrivate::QEnableIf<(&T::st_atimespec, &T::st_mtimespec, true)>::Type get(const T *p, struct timeval *access, struct timeval *modification) +{ + access->tv_sec = p->st_atimespec.tv_sec; + access->tv_usec = p->st_atimespec.tv_nsec / 1000; + + modification->tv_sec = p->st_mtimespec.tv_sec; + modification->tv_usec = p->st_mtimespec.tv_nsec / 1000; +} + +template +static inline typename QtPrivate::QEnableIf<(&T::st_atimensec, &T::st_mtimensec, true)>::Type get(const T *p, struct timeval *access, struct timeval *modification) +{ + access->tv_sec = p->st_atime; + access->tv_usec = p->st_atimensec / 1000; + + modification->tv_sec = p->st_mtime; + modification->tv_usec = p->st_mtimensec / 1000; +} + +} +} +#endif + //static QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data) { @@ -803,6 +841,74 @@ bool QFileSystemEngine::setPermissions(int fd, QFile::Permissions permissions, Q return success; } +//static +bool QFileSystemEngine::setFileTime(int fd, const QDateTime &newDate, QAbstractFileEngine::FileTime time, QSystemError &error) +{ + if (!newDate.isValid() || time == QAbstractFileEngine::CreationTime) { + error = QSystemError(EINVAL, QSystemError::StandardLibraryError); + return false; + } + +#if QT_CONFIG(futimens) + struct timespec ts[2]; + + ts[0].tv_sec = ts[1].tv_sec = 0; + ts[0].tv_nsec = ts[1].tv_nsec = UTIME_OMIT; + + const qint64 msecs = newDate.toMSecsSinceEpoch(); + + if (time == QAbstractFileEngine::AccessTime) { + ts[0].tv_sec = msecs / 1000; + ts[0].tv_nsec = (msecs % 1000) * 1000000; + } else if (time == QAbstractFileEngine::ModificationTime) { + ts[1].tv_sec = msecs / 1000; + ts[1].tv_nsec = (msecs % 1000) * 1000000; + } + + if (futimens(fd, ts) == -1) { + error = QSystemError(errno, QSystemError::StandardLibraryError); + return false; + } + + return true; +#elif QT_CONFIG(futimes) || QT_CONFIG(futimesat) + struct timeval tv[2]; + QT_STATBUF st; + + if (QT_FSTAT(fd, &st) == -1) { + error = QSystemError(errno, QSystemError::StandardLibraryError); + return false; + } + + GetFileTimes::get(&st, &tv[0], &tv[1]); + + const qint64 msecs = newDate.toMSecsSinceEpoch(); + + if (time == QAbstractFileEngine::AccessTime) { + tv[0].tv_sec = msecs / 1000; + tv[0].tv_usec = (msecs % 1000) * 1000; + } else if (time == QAbstractFileEngine::ModificationTime) { + tv[1].tv_sec = msecs / 1000; + tv[1].tv_usec = (msecs % 1000) * 1000; + } + +#if QT_CONFIG(futimes) + if (futimes(fd, tv) == -1) { +#else + if (futimesat(fd, NULL, tv) == -1) { +#endif + error = QSystemError(errno, QSystemError::StandardLibraryError); + return false; + } + + return true; +#else + Q_UNUSED(fd); + error = QSystemError(ENOSYS, QSystemError::StandardLibraryError); + return false; +#endif +} + QString QFileSystemEngine::homePath() { QString home = QFile::decodeName(qgetenv("HOME")); diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 74c6b52a66..5796b1ba66 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -231,6 +231,28 @@ QT_BEGIN_NAMESPACE Q_CORE_EXPORT int qt_ntfs_permission_lookup = 0; +static inline bool toFileTime(const QDateTime &date, FILETIME *fileTime) +{ + SYSTEMTIME lTime; + const QDate d = date.date(); + const QTime t = date.time(); + + lTime.wYear = d.year(); + lTime.wMonth = d.month(); + lTime.wDay = d.day(); + lTime.wHour = t.hour(); + lTime.wMinute = t.minute(); + lTime.wSecond = t.second(); + lTime.wMilliseconds = t.msec(); + lTime.wDayOfWeek = d.dayOfWeek() % 7; + + SYSTEMTIME sTime; + if (!::TzSpecificLocalTimeToSystemTime(0, &lTime, &sTime)) + return false; + + return ::SystemTimeToFileTime(&sTime, fileTime); +} + static QString readSymLink(const QFileSystemEntry &link) { QString result; @@ -571,6 +593,42 @@ QByteArray QFileSystemEngine::id(HANDLE fHandle) } //static +bool QFileSystemEngine::setFileTime(HANDLE fHandle, const QDateTime &newDate, + QAbstractFileEngine::FileTime time, QSystemError &error) +{ + FILETIME fTime; + FILETIME *pLastWrite = NULL; + FILETIME *pLastAccess = NULL; + FILETIME *pCreationTime = NULL; + + switch (time) { + case QAbstractFileEngine::ModificationTime: + pLastWrite = &fTime; + break; + + case QAbstractFileEngine::AccessTime: + pLastAccess = &fTime; + break; + + case QAbstractFileEngine::CreationTime: + pCreationTime = &fTime; + break; + + default: + error = QSystemError(ERROR_INVALID_PARAMETER, QSystemError::NativeError); + return false; + } + + if (!toFileTime(newDate, &fTime)) + return false; + + if (!::SetFileTime(fHandle, pCreationTime, pLastAccess, pLastWrite)) { + error = QSystemError(::GetLastError(), QSystemError::NativeError); + return false; + } + return true; +} + QString QFileSystemEngine::owner(const QFileSystemEntry &entry, QAbstractFileEngine::FileOwner own) { QString name; diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 771810a06e..bb9b3dc87a 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -100,44 +100,6 @@ static inline QString msgOpenDirectory() #endif } -#if !QT_CONFIG(futimens) && (QT_CONFIG(futimes) || QT_CONFIG(futimesat)) -namespace { -namespace GetFileTimes { - -template -static inline typename QtPrivate::QEnableIf<(&T::st_atim, &T::st_mtim, true)>::Type get(const T *p, struct timeval *access, struct timeval *modification) -{ - access->tv_sec = p->st_atim.tv_sec; - access->tv_usec = p->st_atim.tv_nsec / 1000; - - modification->tv_sec = p->st_mtim.tv_sec; - modification->tv_usec = p->st_mtim.tv_nsec / 1000; -} - -template -static inline typename QtPrivate::QEnableIf<(&T::st_atimespec, &T::st_mtimespec, true)>::Type get(const T *p, struct timeval *access, struct timeval *modification) -{ - access->tv_sec = p->st_atimespec.tv_sec; - access->tv_usec = p->st_atimespec.tv_nsec / 1000; - - modification->tv_sec = p->st_mtimespec.tv_sec; - modification->tv_usec = p->st_mtimespec.tv_nsec / 1000; -} - -template -static inline typename QtPrivate::QEnableIf<(&T::st_atimensec, &T::st_mtimensec, true)>::Type get(const T *p, struct timeval *access, struct timeval *modification) -{ - access->tv_sec = p->st_atime; - access->tv_usec = p->st_atimensec / 1000; - - modification->tv_sec = p->st_mtime; - modification->tv_usec = p->st_mtimensec / 1000; -} - -} -} -#endif - /*! \internal */ @@ -654,72 +616,14 @@ bool QFSFileEngine::setFileTime(const QDateTime &newDate, FileTime time) return false; } - if (!newDate.isValid() || time == QAbstractFileEngine::CreationTime) { - setError(QFile::UnspecifiedError, qt_error_string(EINVAL)); - return false; - } - -#if QT_CONFIG(futimens) - struct timespec ts[2]; - - ts[0].tv_sec = ts[1].tv_sec = 0; - ts[0].tv_nsec = ts[1].tv_nsec = UTIME_OMIT; - - const qint64 msecs = newDate.toMSecsSinceEpoch(); - - if (time == QAbstractFileEngine::AccessTime) { - ts[0].tv_sec = msecs / 1000; - ts[0].tv_nsec = (msecs % 1000) * 1000000; - } else if (time == QAbstractFileEngine::ModificationTime) { - ts[1].tv_sec = msecs / 1000; - ts[1].tv_nsec = (msecs % 1000) * 1000000; - } - - if (futimens(d->nativeHandle(), ts) == -1) { - setError(QFile::PermissionsError, qt_error_string()); + QSystemError error; + if (!QFileSystemEngine::setFileTime(d->nativeHandle(), newDate, time, error)) { + setError(QFile::PermissionsError, error.toString()); return false; } d->metaData.clearFlags(QFileSystemMetaData::Times); - return true; -#elif QT_CONFIG(futimes) || QT_CONFIG(futimesat) - struct timeval tv[2]; - QT_STATBUF st; - - if (QT_FSTAT(d->nativeHandle(), &st) == -1) { - setError(QFile::PermissionsError, qt_error_string()); - return false; - } - - GetFileTimes::get(&st, &tv[0], &tv[1]); - - const qint64 msecs = newDate.toMSecsSinceEpoch(); - - if (time == QAbstractFileEngine::AccessTime) { - tv[0].tv_sec = msecs / 1000; - tv[0].tv_usec = (msecs % 1000) * 1000; - } else if (time == QAbstractFileEngine::ModificationTime) { - tv[1].tv_sec = msecs / 1000; - tv[1].tv_usec = (msecs % 1000) * 1000; - } - -#if QT_CONFIG(futimes) - if (futimes(d->nativeHandle(), tv) == -1) { -#else - if (futimesat(d->nativeHandle(), NULL, tv) == -1) { -#endif - setError(QFile::PermissionsError, qt_error_string()); - return false; - } - - d->metaData.clearFlags(QFileSystemMetaData::Times); - - return true; -#else - setError(QFile::UnspecifiedError, qt_error_string(ENOSYS)); - return false; -#endif } uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 023354fd8f..50a8a0e55a 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -80,39 +80,6 @@ static inline bool isUncPath(const QString &path) && path.size() > 2 && path.at(2) != QLatin1Char('.')); } -static inline void QDateTimeToSystemTime(const QDateTime &date, SYSTEMTIME *systemTime) -{ - const QDate d = date.date(); - const QTime t = date.time(); - - systemTime->wYear = d.year(); - systemTime->wMonth = d.month(); - systemTime->wDay = d.day(); - systemTime->wHour = t.hour(); - systemTime->wMinute = t.minute(); - systemTime->wSecond = t.second(); - systemTime->wMilliseconds = t.msec(); - systemTime->wDayOfWeek = d.dayOfWeek() % 7; -} - -static inline bool QDateTimeToFileTime(const QDateTime &date, FILETIME *fileTime) -{ - SYSTEMTIME sTime; - -#if defined(Q_OS_WINCE) - QDateTimeToSystemTime(date, &sTime); -#else - SYSTEMTIME lTime; - - QDateTimeToSystemTime(date, &lTime); - - if (!::TzSpecificLocalTimeToSystemTime(0, &lTime, &sTime)) - return false; -#endif - - return ::SystemTimeToFileTime(&sTime, fileTime); -} - /*! \internal */ @@ -903,52 +870,25 @@ bool QFSFileEngine::setFileTime(const QDateTime &newDate, FileTime time) } HANDLE handle = d->fileHandle; - -#ifndef Q_OS_WINCE if (handle == INVALID_HANDLE_VALUE) { if (d->fh) handle = reinterpret_cast(::_get_osfhandle(QT_FILENO(d->fh))); else if (d->fd != -1) handle = reinterpret_cast(::_get_osfhandle(d->fd)); } -#endif if (handle == INVALID_HANDLE_VALUE) { setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED)); return false; } - FILETIME fTime; - FILETIME *pLastWrite = NULL; - FILETIME *pLastAccess = NULL; - FILETIME *pCreationTime = NULL; - - switch (time) { - case QAbstractFileEngine::ModificationTime: - pLastWrite = &fTime; - break; - - case QAbstractFileEngine::AccessTime: - pLastAccess = &fTime; - break; - - case QAbstractFileEngine::CreationTime: - pCreationTime = &fTime; - break; - } - - if (!QDateTimeToFileTime(newDate, &fTime)) { - setError(QFile::UnspecifiedError, qt_error_string()); - return false; - } - - if (!::SetFileTime(handle, pCreationTime, pLastAccess, pLastWrite)) { - setError(QFile::PermissionsError, qt_error_string()); + QSystemError error; + if (!QFileSystemEngine::setFileTime(handle, newDate, time, error)) { + setError(QFile::PermissionsError, error.toString()); return false; } d->metaData.clearFlags(QFileSystemMetaData::Times); - return true; }