Move platform-specific code from QFSFileEngine to QFileSystemEngine

Change-Id: I8d96dea9955d4c749b99fffd14cd9395174ba005
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Thiago Macieira 2017-07-02 10:28:39 -07:00
parent 261c6713bd
commit db433bdf65
5 changed files with 178 additions and 162 deletions

View File

@ -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();

View File

@ -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 <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
//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"));

View File

@ -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;

View File

@ -100,44 +100,6 @@ 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
*/
@ -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)

View File

@ -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<HANDLE>(::_get_osfhandle(QT_FILENO(d->fh)));
else if (d->fd != -1)
handle = reinterpret_cast<HANDLE>(::_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;
}