diff options
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qabstractfileengine.cpp | 11 | ||||
-rw-r--r-- | src/corelib/io/qabstractfileengine_p.h | 1 | ||||
-rw-r--r-- | src/corelib/io/qfile.cpp | 4 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_p.h | 2 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_unix.cpp | 14 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_win.cpp | 22 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine.cpp | 22 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_p.h | 1 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_unix.cpp | 8 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_win.cpp | 22 | ||||
-rw-r--r-- | src/corelib/io/qloggingcategory.cpp | 15 | ||||
-rw-r--r-- | src/corelib/io/qresource.cpp | 3 | ||||
-rw-r--r-- | src/corelib/io/qwindowspipereader.cpp | 22 | ||||
-rw-r--r-- | src/corelib/io/qwindowspipereader_p.h | 2 | ||||
-rw-r--r-- | src/corelib/io/qwindowspipewriter.cpp | 22 | ||||
-rw-r--r-- | src/corelib/io/qwindowspipewriter_p.h | 2 |
16 files changed, 127 insertions, 46 deletions
diff --git a/src/corelib/io/qabstractfileengine.cpp b/src/corelib/io/qabstractfileengine.cpp index 169e933546..7a603544f3 100644 --- a/src/corelib/io/qabstractfileengine.cpp +++ b/src/corelib/io/qabstractfileengine.cpp @@ -678,6 +678,17 @@ bool QAbstractFileEngine::setPermissions(uint perms) } /*! + \since 5.9 + + Return an identifier that (hopefully) uniquely identifies this file in the + system. Returns an invalid QByteArray() if that cannot be calculated. +*/ +QByteArray QAbstractFileEngine::id() const +{ + return QByteArray(); +} + +/*! Return the file engine's current file name in the format specified by \a file. diff --git a/src/corelib/io/qabstractfileengine_p.h b/src/corelib/io/qabstractfileengine_p.h index 5685a39e81..47b3a624fe 100644 --- a/src/corelib/io/qabstractfileengine_p.h +++ b/src/corelib/io/qabstractfileengine_p.h @@ -141,6 +141,7 @@ public: virtual QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const; virtual FileFlags fileFlags(FileFlags type=FileInfoAll) const; virtual bool setPermissions(uint perms); + virtual QByteArray id() const; virtual QString fileName(FileName file=DefaultName) const; virtual uint ownerId(FileOwner) const; virtual QString owner(FileOwner) const; diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index c7a06e49d5..b93fea1038 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -571,7 +571,9 @@ QFile::rename(const QString &newName) // Note: this does not take file engines into account. QByteArray targetId = QFileSystemEngine::id(QFileSystemEntry(newName)); if (!targetId.isNull()) { - QByteArray fileId = QFileSystemEngine::id(QFileSystemEntry(d->fileName)); + QByteArray fileId = d->fileEngine ? + d->fileEngine->id() : + QFileSystemEngine::id(QFileSystemEntry(d->fileName)); if (fileId != targetId || d->fileName.compare(newName, Qt::CaseInsensitive)) { // ### Race condition. If a file is moved in after this, it /will/ be // overwritten. On Unix, the proper solution is to use hardlinks: diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index 196ed8df69..e3e52f6eaa 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -92,6 +92,7 @@ public: QFileSystemMetaData::MetaDataFlags what); #if defined(Q_OS_UNIX) static bool fillMetaData(int fd, QFileSystemMetaData &data); // what = PosixStatFlags + static QByteArray id(int fd); static bool setPermissions(int fd, QFile::Permissions permissions, QSystemError &error, QFileSystemMetaData *data = nullptr); #endif @@ -104,6 +105,7 @@ public: QFileSystemMetaData::MetaDataFlags what); static bool fillPermissions(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what); + static QByteArray id(HANDLE fHandle); static QString owner(const QFileSystemEntry &entry, QAbstractFileEngine::FileOwner own); static QString nativeAbsoluteFilePath(const QString &path); #endif diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 940a0a2122..b0c23e3f82 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -328,6 +328,20 @@ QByteArray QFileSystemEngine::id(const QFileSystemEntry &entry) } //static +QByteArray QFileSystemEngine::id(int id) +{ + QT_STATBUF statResult; + if (QT_FSTAT(id, &statResult)) { + qErrnoWarning("fstat() failed for fd %d", id); + return QByteArray(); + } + QByteArray result = QByteArray::number(quint64(statResult.st_dev), 16); + result += ':'; + result += QByteArray::number(quint64(statResult.st_ino)); + return result; +} + +//static QString QFileSystemEngine::resolveUserName(uint userId) { #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 889fbfea7b..eac6519de5 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -561,19 +561,21 @@ typedef struct _FILE_ID_INFO { // File ID for Windows up to version 7. static inline QByteArray fileId(HANDLE handle) { - QByteArray result; #ifndef Q_OS_WINRT BY_HANDLE_FILE_INFORMATION info; if (GetFileInformationByHandle(handle, &info)) { - result = QByteArray::number(uint(info.nFileIndexLow), 16); - result += ':'; - result += QByteArray::number(uint(info.nFileIndexHigh), 16); + char buffer[sizeof "01234567:0123456701234567"]; + qsnprintf(buffer, sizeof(buffer), "%lx:%08lx%08lx", + info.dwVolumeSerialNumber, + info.nFileIndexHigh, + info.nFileIndexLow); + return buffer; } #else // !Q_OS_WINRT Q_UNUSED(handle); Q_UNIMPLEMENTED(); #endif // Q_OS_WINRT - return result; + return QByteArray(); } // File ID for Windows starting from version 8. @@ -609,14 +611,20 @@ QByteArray QFileSystemEngine::id(const QFileSystemEntry &entry) FILE_SHARE_READ, OPEN_EXISTING, NULL); #endif // Q_OS_WINRT if (handle != INVALID_HANDLE_VALUE) { - result = QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8 ? - fileIdWin8(handle) : fileId(handle); + result = id(handle); CloseHandle(handle); } return result; } //static +QByteArray QFileSystemEngine::id(HANDLE fHandle) +{ + return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8 ? + fileIdWin8(HANDLE(fHandle)) : fileId(HANDLE(fHandle)); +} + +//static QString QFileSystemEngine::owner(const QFileSystemEntry &entry, QAbstractFileEngine::FileOwner own) { QString name; diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index b7f2f0d645..037deb8942 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -277,7 +277,7 @@ bool QFSFileEnginePrivate::openFh(QIODevice::OpenMode openMode, FILE *fh) if (ret != 0) { q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, - qt_error_string(int(errno))); + QSystemError::stdString()); this->openMode = QIODevice::NotOpen; this->fh = 0; @@ -341,7 +341,7 @@ bool QFSFileEnginePrivate::openFd(QIODevice::OpenMode openMode, int fd) if (ret == -1) { q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, - qt_error_string(int(errno))); + QSystemError::stdString()); this->openMode = QIODevice::NotOpen; this->fd = -1; @@ -400,7 +400,7 @@ bool QFSFileEnginePrivate::closeFdFh() if (!flushed || !closed) { if (flushed) { // If not flushed, we want the flush error to fall through. - q->setError(QFile::UnspecifiedError, qt_error_string(errno)); + q->setError(QFile::UnspecifiedError, QSystemError::stdString()); } return false; } @@ -452,7 +452,7 @@ bool QFSFileEnginePrivate::flushFh() if (ret != 0) { q->setError(errno == ENOSPC ? QFile::ResourceError : QFile::WriteError, - qt_error_string(errno)); + QSystemError::stdString()); return false; } return true; @@ -567,14 +567,14 @@ bool QFSFileEnginePrivate::seekFdFh(qint64 pos) } while (ret != 0 && errno == EINTR); if (ret != 0) { - q->setError(QFile::ReadError, qt_error_string(int(errno))); + q->setError(QFile::ReadError, QSystemError::stdString()); return false; } } else { // Unbuffered stdio mode. if (QT_LSEEK(fd, QT_OFF_T(pos), SEEK_SET) == -1) { qWarning("QFile::at: Cannot set file position %lld", pos); - q->setError(QFile::PositionError, qt_error_string(errno)); + q->setError(QFile::PositionError, QSystemError::stdString()); return false; } } @@ -616,7 +616,7 @@ qint64 QFSFileEnginePrivate::readFdFh(char *data, qint64 len) Q_Q(QFSFileEngine); if (len < 0 || len != qint64(size_t(len))) { - q->setError(QFile::ReadError, qt_error_string(EINVAL)); + q->setError(QFile::ReadError, QSystemError::stdString(EINVAL)); return -1; } @@ -662,7 +662,7 @@ qint64 QFSFileEnginePrivate::readFdFh(char *data, qint64 len) if (!eof && readBytes == 0) { readBytes = -1; - q->setError(QFile::ReadError, qt_error_string(errno)); + q->setError(QFile::ReadError, QSystemError::stdString()); } return readBytes; @@ -708,7 +708,7 @@ qint64 QFSFileEnginePrivate::readLineFdFh(char *data, qint64 maxlen) // solves this. if (!fgets(data, int(maxlen + 1), fh)) { if (!feof(fh)) - q->setError(QFile::ReadError, qt_error_string(int(errno))); + q->setError(QFile::ReadError, QSystemError::stdString()); return -1; // error } @@ -748,7 +748,7 @@ qint64 QFSFileEnginePrivate::writeFdFh(const char *data, qint64 len) Q_Q(QFSFileEngine); if (len < 0 || len != qint64(size_t(len))) { - q->setError(QFile::WriteError, qt_error_string(EINVAL)); + q->setError(QFile::WriteError, QSystemError::stdString(EINVAL)); return -1; } @@ -785,7 +785,7 @@ qint64 QFSFileEnginePrivate::writeFdFh(const char *data, qint64 len) if (len && writtenBytes == 0) { writtenBytes = -1; - q->setError(errno == ENOSPC ? QFile::ResourceError : QFile::WriteError, qt_error_string(errno)); + q->setError(errno == ENOSPC ? QFile::ResourceError : QFile::WriteError, QSystemError::stdString()); } else { // reset the cached size, if any metaData.clearFlags(QFileSystemMetaData::SizeAttribute); diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 80dd9363db..f352fcd475 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -93,6 +93,7 @@ public: QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const Q_DECL_OVERRIDE; FileFlags fileFlags(FileFlags type) const Q_DECL_OVERRIDE; bool setPermissions(uint perms) Q_DECL_OVERRIDE; + QByteArray id() const override; QString fileName(FileName file) const Q_DECL_OVERRIDE; uint ownerId(FileOwner) const Q_DECL_OVERRIDE; QString owner(FileOwner) const Q_DECL_OVERRIDE; diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 69961ff76a..a717a3e236 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -542,6 +542,14 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const return ret; } +QByteArray QFSFileEngine::id() const +{ + Q_D(const QFSFileEngine); + if (d->fd != -1) + return QFileSystemEngine::id(d->fd); + return QFileSystemEngine::id(d->fileEntry); +} + QString QFSFileEngine::fileName(FileName file) const { Q_D(const QFSFileEngine); diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index d749e32447..351c4601d1 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -285,7 +285,7 @@ qint64 QFSFileEnginePrivate::nativeSize() const filled = doStat(QFileSystemMetaData::SizeAttribute); if (!filled) { - thatQ->setError(QFile::UnspecifiedError, qt_error_string(errno)); + thatQ->setError(QFile::UnspecifiedError, QSystemError::stdString()); return 0; } return metaData.size(); @@ -352,7 +352,7 @@ qint64 QFSFileEnginePrivate::nativeRead(char *data, qint64 maxlen) if (fh || fd != -1) { // stdio / stdlib mode. if (fh && nativeIsSequential() && feof(fh)) { - q->setError(QFile::ReadError, qt_error_string(int(errno))); + q->setError(QFile::ReadError, QSystemError::stdString()); return -1; } @@ -751,6 +751,24 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil return ret; } +QByteArray QFSFileEngine::id() const +{ + Q_D(const QFSFileEngine); + HANDLE h = d->fileHandle; + if (h == INVALID_HANDLE_VALUE) { + int localFd = d->fd; + if (d->fh && d->fileEntry.isEmpty()) + localFd = QT_FILENO(d->fh); + if (localFd != -1) + h = HANDLE(_get_osfhandle(localFd)); + } + if (h != INVALID_HANDLE_VALUE) + return QFileSystemEngine::id(h); + + // file is not open, try by path + return QFileSystemEngine::id(d->fileEntry); +} + QString QFSFileEngine::fileName(FileName file) const { Q_D(const QFSFileEngine); diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index 69af936bca..4256d4b6e1 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -334,12 +334,11 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const /*! Changes the message type \a type for the category to \a enable. - \note Changes only affect the current QLoggingCategory object, and won't - change the settings of other objects for the same category name. - Use either \l setFilterRules() or \l installFilter() to change the - configuration globally. + This method is meant to be used only from inside a filter + installed by \l installFilter(). See \l {Configuring Categories} for + an overview on how to configure categories globally. - \note \c QtFatalMsg cannot be changed. It will always return \c true. + \note \c QtFatalMsg cannot be changed. It will always remain \c true. */ void QLoggingCategory::setEnabled(QtMsgType type, bool enable) { @@ -411,8 +410,8 @@ QLoggingCategory *QLoggingCategory::defaultCategory() filter is free to change the respective category configuration with \l setEnabled(). - The filter might be called concurrently from different threads, and - therefore has to be reentrant. + The filter might be called from different threads, but never concurrently. + The filter shall not call any static functions of QLoggingCategory. Example: \snippet qloggingcategory/main.cpp 21 diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 984ed23812..c1187e5145 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -53,6 +53,7 @@ #include <qshareddata.h> #include <qplatformdefs.h> #include "private/qabstractfileengine_p.h" +#include "private/qsystemerror_p.h" #ifdef Q_OS_UNIX # include "private/qcore_unix_p.h" @@ -1282,7 +1283,7 @@ bool QResourceFileEngine::open(QIODevice::OpenMode flags) return false; d->uncompress(); if (!d->resource.isValid()) { - d->errorString = qt_error_string(ENOENT); + d->errorString = QSystemError::stdString(ENOENT); return false; } return true; diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp index b68e9e6d4b..ef5ff2d827 100644 --- a/src/corelib/io/qwindowspipereader.cpp +++ b/src/corelib/io/qwindowspipereader.cpp @@ -57,7 +57,7 @@ void QWindowsPipeReader::Overlapped::clear() QWindowsPipeReader::QWindowsPipeReader(QObject *parent) : QObject(parent), handle(INVALID_HANDLE_VALUE), - overlapped(this), + overlapped(nullptr), readBufferMaxSize(0), actualReadBufferSize(0), stopped(true), @@ -74,6 +74,7 @@ QWindowsPipeReader::QWindowsPipeReader(QObject *parent) QWindowsPipeReader::~QWindowsPipeReader() { stop(); + delete overlapped; } /*! @@ -95,14 +96,16 @@ void QWindowsPipeReader::stop() { stopped = true; if (readSequenceStarted) { - if (!CancelIoEx(handle, &overlapped)) { + overlapped->pipeReader = nullptr; + if (!CancelIoEx(handle, overlapped)) { const DWORD dwError = GetLastError(); if (dwError != ERROR_NOT_FOUND) { - qErrnoWarning(dwError, "QWindowsPipeReader: qt_cancelIo on handle %x failed.", + qErrnoWarning(dwError, "QWindowsPipeReader: CancelIoEx on handle %p failed.", handle); } } - waitForNotification(-1); + overlapped = nullptr; // The object will be deleted in the I/O callback. + readSequenceStarted = false; } } @@ -223,8 +226,10 @@ void QWindowsPipeReader::startAsyncRead() stopped = false; readSequenceStarted = true; - overlapped.clear(); - if (!ReadFileEx(handle, ptr, bytesToRead, &overlapped, &readFileCompleted)) { + if (!overlapped) + overlapped = new Overlapped(this); + overlapped->clear(); + if (!ReadFileEx(handle, ptr, bytesToRead, overlapped, &readFileCompleted)) { readSequenceStarted = false; const DWORD dwError = GetLastError(); @@ -251,7 +256,10 @@ void QWindowsPipeReader::readFileCompleted(DWORD errorCode, DWORD numberOfBytesT OVERLAPPED *overlappedBase) { Overlapped *overlapped = static_cast<Overlapped *>(overlappedBase); - overlapped->pipeReader->notified(errorCode, numberOfBytesTransfered); + if (overlapped->pipeReader) + overlapped->pipeReader->notified(errorCode, numberOfBytesTransfered); + else + delete overlapped; } /*! diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h index 74ff5250ac..e52aa4c33d 100644 --- a/src/corelib/io/qwindowspipereader_p.h +++ b/src/corelib/io/qwindowspipereader_p.h @@ -105,7 +105,7 @@ private: }; HANDLE handle; - Overlapped overlapped; + Overlapped *overlapped; qint64 readBufferMaxSize; QRingBuffer readBuffer; qint64 actualReadBufferSize; diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index 06a3572fad..8e3de2d620 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -56,7 +56,7 @@ void QWindowsPipeWriter::Overlapped::clear() QWindowsPipeWriter::QWindowsPipeWriter(HANDLE pipeWriteEnd, QObject *parent) : QObject(parent), handle(pipeWriteEnd), - overlapped(this), + overlapped(nullptr), pendingBytesWrittenValue(0), stopped(true), writeSequenceStarted(false), @@ -71,6 +71,7 @@ QWindowsPipeWriter::QWindowsPipeWriter(HANDLE pipeWriteEnd, QObject *parent) QWindowsPipeWriter::~QWindowsPipeWriter() { stop(); + delete overlapped; } bool QWindowsPipeWriter::waitForWrite(int msecs) @@ -121,7 +122,10 @@ void QWindowsPipeWriter::writeFileCompleted(DWORD errorCode, DWORD numberOfBytes OVERLAPPED *overlappedBase) { Overlapped *overlapped = static_cast<Overlapped *>(overlappedBase); - overlapped->pipeWriter->notified(errorCode, numberOfBytesTransfered); + if (overlapped->pipeWriter) + overlapped->pipeWriter->notified(errorCode, numberOfBytesTransfered); + else + delete overlapped; } /*! @@ -183,12 +187,14 @@ bool QWindowsPipeWriter::write(const QByteArray &ba) if (writeSequenceStarted) return false; - overlapped.clear(); + if (!overlapped) + overlapped = new Overlapped(this); + overlapped->clear(); buffer = ba; stopped = false; writeSequenceStarted = true; if (!WriteFileEx(handle, buffer.constData(), buffer.size(), - &overlapped, &writeFileCompleted)) { + overlapped, &writeFileCompleted)) { writeSequenceStarted = false; buffer.clear(); qErrnoWarning("QWindowsPipeWriter::write failed."); @@ -204,14 +210,16 @@ void QWindowsPipeWriter::stop() bytesWrittenPending = false; pendingBytesWrittenValue = 0; if (writeSequenceStarted) { - if (!CancelIoEx(handle, &overlapped)) { + overlapped->pipeWriter = nullptr; + if (!CancelIoEx(handle, overlapped)) { const DWORD dwError = GetLastError(); if (dwError != ERROR_NOT_FOUND) { - qErrnoWarning(dwError, "QWindowsPipeWriter: qt_cancelIo on handle %x failed.", + qErrnoWarning(dwError, "QWindowsPipeWriter: CancelIoEx on handle %p failed.", handle); } } - waitForNotification(-1); + overlapped = nullptr; // The object will be deleted in the I/O callback. + writeSequenceStarted = false; } } diff --git a/src/corelib/io/qwindowspipewriter_p.h b/src/corelib/io/qwindowspipewriter_p.h index a4ecfa3bf8..d6671c3f27 100644 --- a/src/corelib/io/qwindowspipewriter_p.h +++ b/src/corelib/io/qwindowspipewriter_p.h @@ -143,7 +143,7 @@ private: }; HANDLE handle; - Overlapped overlapped; + Overlapped *overlapped; QByteArray buffer; qint64 pendingBytesWrittenValue; bool stopped; |