diff options
Diffstat (limited to 'src/corelib/io/qfsfileengine_unix.cpp')
-rw-r--r-- | src/corelib/io/qfsfileengine_unix.cpp | 148 |
1 files changed, 44 insertions, 104 deletions
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index c613368a91..c040d67862 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -65,46 +65,6 @@ QT_BEGIN_NAMESPACE /*! \internal - Returns the stdlib open string corresponding to a QIODevice::OpenMode. -*/ -static inline QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QFileSystemEntry &fileEntry, - QFileSystemMetaData &metaData) -{ - QByteArray mode; - if ((flags & QIODevice::ReadOnly) && !(flags & QIODevice::Truncate)) { - mode = "rb"; - if (flags & QIODevice::WriteOnly) { - metaData.clearFlags(QFileSystemMetaData::FileType); - if (!fileEntry.isEmpty() - && QFileSystemEngine::fillMetaData(fileEntry, metaData, QFileSystemMetaData::FileType) - && metaData.isFile()) { - mode += '+'; - } else { - mode = "wb+"; - } - } - } else if (flags & QIODevice::WriteOnly) { - mode = "wb"; - if (flags & QIODevice::ReadOnly) - mode += '+'; - } - if (flags & QIODevice::Append) { - mode = "ab"; - if (flags & QIODevice::ReadOnly) - mode += '+'; - } - -#if defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0207 - // must be glibc >= 2.7 - mode += 'e'; -#endif - - return mode; -} - -/*! - \internal - Returns the stdio open flags corresponding to a QIODevice::OpenMode. */ static inline int openModeToOpenFlags(QIODevice::OpenMode mode) @@ -130,17 +90,6 @@ static inline int openModeToOpenFlags(QIODevice::OpenMode mode) return oflags; } -/*! - \internal - - Sets the file descriptor to close on exec. That is, the file - descriptor is not inherited by child processes. -*/ -static inline bool setCloseOnExec(int fd) -{ - return fd != -1 && fcntl(fd, F_SETFD, FD_CLOEXEC) != -1; -} - static inline QString msgOpenDirectory() { const char message[] = QT_TRANSLATE_NOOP("QIODevice", "file to open is a directory"); @@ -158,6 +107,8 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) { Q_Q(QFSFileEngine); + Q_ASSERT_X(openMode & QIODevice::Unbuffered, "QFSFileEngine::open", + "QFSFileEngine no longer supports buffered mode; upper layer must buffer"); if (openMode & QIODevice::Unbuffered) { int flags = openModeToOpenFlags(openMode); @@ -199,49 +150,6 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) } fh = 0; - } else { - QByteArray fopenMode = openModeToFopenMode(openMode, fileEntry, metaData); - - // Try to open the file in buffered mode. - do { - fh = QT_FOPEN(fileEntry.nativeFilePath().constData(), fopenMode.constData()); - } while (!fh && errno == EINTR); - - // On failure, return and report the error. - if (!fh) { - q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, - qt_error_string(int(errno))); - return false; - } - - if (!(openMode & QIODevice::WriteOnly)) { - // we don't need this check if we tried to open for writing because then - // we had received EISDIR anyway. - if (QFileSystemEngine::fillMetaData(QT_FILENO(fh), metaData) - && metaData.isDirectory()) { - q->setError(QFile::OpenError, msgOpenDirectory()); - fclose(fh); - return false; - } - } - - setCloseOnExec(fileno(fh)); // ignore failure - - // Seek to the end when in Append mode. - if (openMode & QIODevice::Append) { - int ret; - do { - ret = QT_FSEEK(fh, 0, SEEK_END); - } while (ret == -1 && errno == EINTR); - - if (ret == -1) { - q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, - qt_error_string(int(errno))); - return false; - } - } - - fd = -1; } closeFileHandle = true; @@ -416,8 +324,14 @@ bool QFSFileEngine::copy(const QString &newName) bool QFSFileEngine::renameOverwrite(const QString &newName) { - // On Unix, rename() overwrites. - return rename(newName); + Q_D(QFSFileEngine); + QSystemError error; + bool ret = QFileSystemEngine::renameOverwriteFile(d->fileEntry, QFileSystemEntry(newName), error); + + if (!ret) + setError(QFile::RenameError, error.toString()); + + return ret; } bool QFSFileEngine::rename(const QString &newName) @@ -549,11 +463,14 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const | QFileSystemMetaData::LinkType | QFileSystemMetaData::FileType | QFileSystemMetaData::DirectoryType - | QFileSystemMetaData::BundleType; + | QFileSystemMetaData::BundleType + | QFileSystemMetaData::WasDeletedAttribute; if (type & FlagsMask) queryFlags |= QFileSystemMetaData::HiddenAttribute | QFileSystemMetaData::ExistsAttribute; + else if (type & ExistsFlag) + queryFlags |= QFileSystemMetaData::WasDeletedAttribute; queryFlags |= QFileSystemMetaData::LinkType; @@ -585,7 +502,8 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const } if (type & FlagsMask) { - if (exists) + // the inode existing does not mean the file exists + if (!d->metaData.wasDeleted()) ret |= ExistsFlag; if (d->fileEntry.isRoot()) ret |= RootFlag; @@ -689,14 +607,23 @@ bool QFSFileEngine::setSize(qint64 size) return ret; } -QDateTime QFSFileEngine::fileTime(FileTime time) const +bool QFSFileEngine::setFileTime(const QDateTime &newDate, FileTime time) { - Q_D(const QFSFileEngine); + Q_D(QFSFileEngine); + + if (d->openMode == QIODevice::NotOpen) { + setError(QFile::PermissionsError, qt_error_string(EACCES)); + return false; + } - if (d->doStat(QFileSystemMetaData::Times)) - return d->metaData.fileTime(time); + QSystemError error; + if (!QFileSystemEngine::setFileTime(d->nativeHandle(), newDate, time, error)) { + setError(QFile::PermissionsError, error.toString()); + return false; + } - return QDateTime(); + d->metaData.clearFlags(QFileSystemMetaData::Times); + return true; } uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags) @@ -715,7 +642,6 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla #endif Q_Q(QFSFileEngine); - Q_UNUSED(flags); if (openMode == QIODevice::NotOpen) { q->setError(QFile::PermissionsError, qt_error_string(int(EACCES))); return 0; @@ -806,6 +732,20 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr) #endif } +/*! + \reimp +*/ +bool QFSFileEngine::cloneTo(QAbstractFileEngine *target) +{ + Q_D(QFSFileEngine); + if ((target->fileFlags(LocalDiskFlag) & LocalDiskFlag) == 0) + return false; + + int srcfd = d->nativeHandle(); + int dstfd = target->handle(); + return QFileSystemEngine::cloneFile(srcfd, dstfd, d->metaData); +} + QT_END_NAMESPACE #endif // QT_NO_FSFILEENGINE |