diff options
Diffstat (limited to 'src/corelib/io/qfsfileengine_unix.cpp')
-rw-r--r-- | src/corelib/io/qfsfileengine_unix.cpp | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 51938d6967..4617d09874 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -100,6 +100,44 @@ static inline QString msgOpenDirectory() #endif } +#if !QT_CONFIG(futimens) && (QT_CONFIG(futimes) || QT_CONFIG(futimesat)) +namespace { +namespace GetFileTimes { + +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) +{ + 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 <typename T> +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 <typename T> +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 */ @@ -584,6 +622,83 @@ bool QFSFileEngine::setSize(qint64 size) return ret; } +bool QFSFileEngine::setFileTime(const QDateTime &newDate, FileTime time) +{ + Q_D(QFSFileEngine); + + if (d->openMode == QIODevice::NotOpen) { + setError(QFile::PermissionsError, qt_error_string(EACCES)); + 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()); + 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 +} + QDateTime QFSFileEngine::fileTime(FileTime time) const { Q_D(const QFSFileEngine); |