summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io')
-rw-r--r--src/corelib/io/io.pri1
-rw-r--r--src/corelib/io/qabstractfileengine.cpp2
-rw-r--r--src/corelib/io/qdir.cpp5
-rw-r--r--src/corelib/io/qdiriterator.cpp2
-rw-r--r--src/corelib/io/qfile.cpp4
-rw-r--r--src/corelib/io/qfile.h10
-rw-r--r--src/corelib/io/qfiledevice.cpp2
-rw-r--r--src/corelib/io/qfileinfo.cpp21
-rw-r--r--src/corelib/io/qfileinfo.h1
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp6
-rw-r--r--src/corelib/io/qfilesystemmetadata_p.h21
-rw-r--r--src/corelib/io/qfilesystemwatcher.cpp2
-rw-r--r--src/corelib/io/qfilesystemwatcher_inotify.cpp2
-rw-r--r--src/corelib/io/qfilesystemwatcher_win.cpp1
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp4
-rw-r--r--src/corelib/io/qiodevice.cpp2
-rw-r--r--src/corelib/io/qloggingcategory.cpp2
-rw-r--r--src/corelib/io/qnoncontiguousbytedevice.cpp20
-rw-r--r--src/corelib/io/qprocess.cpp32
-rw-r--r--src/corelib/io/qprocess.h3
-rw-r--r--src/corelib/io/qprocess_unix.cpp37
-rw-r--r--src/corelib/io/qprocess_win.cpp15
-rw-r--r--src/corelib/io/qresource.cpp230
-rw-r--r--src/corelib/io/qresource.h5
-rw-r--r--src/corelib/io/qsavefile.cpp2
-rw-r--r--src/corelib/io/qsettings.cpp27
-rw-r--r--src/corelib/io/qsettings_p.h13
-rw-r--r--src/corelib/io/qsettings_wasm.cpp259
-rw-r--r--src/corelib/io/qstandardpaths.cpp68
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp2
-rw-r--r--src/corelib/io/qtemporaryfile.cpp6
-rw-r--r--src/corelib/io/qurl.cpp2
32 files changed, 588 insertions, 221 deletions
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index fe81689932..c4c6f41387 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -136,6 +136,7 @@ qtConfig(settings) {
} else: darwin:!nacl {
SOURCES += io/qsettings_mac.cpp
}
+ wasm : SOURCES += io/qsettings_wasm.cpp
}
win32 {
diff --git a/src/corelib/io/qabstractfileengine.cpp b/src/corelib/io/qabstractfileengine.cpp
index 8a1679c5af..070139b608 100644
--- a/src/corelib/io/qabstractfileengine.cpp
+++ b/src/corelib/io/qabstractfileengine.cpp
@@ -658,7 +658,7 @@ QStringList QAbstractFileEngine::entryList(QDir::Filters filters, const QStringL
QAbstractFileEngine::FileFlags QAbstractFileEngine::fileFlags(FileFlags type) const
{
Q_UNUSED(type);
- return nullptr;
+ return {};
}
/*!
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index fae935fc24..526702d151 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -2372,8 +2372,9 @@ static QString qt_cleanPath(const QString &path, bool *ok)
}
/*!
- Returns \a path with directory separators normalized (converted to "/") and
- redundant ones removed, and "."s and ".."s resolved (as far as possible).
+ Returns \a path with directory separators normalized (that is, platform-native
+ separators converted to "/") and redundant ones removed, and "."s and ".."s
+ resolved (as far as possible).
Symbolic links are kept. This function does not return the
canonical path, but rather the simplest version of the input.
diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp
index ce436b06e3..1cf6b1be08 100644
--- a/src/corelib/io/qdiriterator.cpp
+++ b/src/corelib/io/qdiriterator.cpp
@@ -181,7 +181,7 @@ QDirIteratorPrivate::QDirIteratorPrivate(const QFileSystemEntry &entry, const QS
#elif QT_CONFIG(regularexpression)
nameRegExps.reserve(nameFilters.size());
for (const auto &filter : nameFilters) {
- QString re = QRegularExpression::anchoredPattern(QRegularExpression::wildcardToRegularExpression(filter));
+ QString re = QRegularExpression::wildcardToRegularExpression(filter);
nameRegExps.append(
QRegularExpression(re, (filters & QDir::CaseSensitive) ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption));
}
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index 95f03ef816..5320ae2986 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -251,7 +251,7 @@ QFile::QFile(QFilePrivate &dd)
Constructs a QFile object.
*/
QFile::QFile()
- : QFileDevice(*new QFilePrivate, 0)
+ : QFileDevice(*new QFilePrivate, nullptr)
{
}
/*!
@@ -265,7 +265,7 @@ QFile::QFile(QObject *parent)
Constructs a new file object to represent the file with the given \a name.
*/
QFile::QFile(const QString &name)
- : QFileDevice(*new QFilePrivate, 0)
+ : QFileDevice(*new QFilePrivate, nullptr)
{
Q_D(QFile);
d->fileName = name;
diff --git a/src/corelib/io/qfile.h b/src/corelib/io/qfile.h
index cf1465ec70..2099b2852f 100644
--- a/src/corelib/io/qfile.h
+++ b/src/corelib/io/qfile.h
@@ -84,6 +84,10 @@ public:
// note: duplicated in qglobal.cpp (qEnvironmentVariable)
return QString::fromUtf8(localFileName).normalized(QString::NormalizationForm_C);
}
+ static inline QString decodeName(const char *localFileName)
+ {
+ return QString::fromUtf8(localFileName).normalized(QString::NormalizationForm_C);
+ }
#else
static inline QByteArray encodeName(const QString &fileName)
{
@@ -93,9 +97,11 @@ public:
{
return QString::fromLocal8Bit(localFileName);
}
+ static inline QString decodeName(const char *localFileName)
+ {
+ return QString::fromLocal8Bit(localFileName);
+ }
#endif
- inline static QString decodeName(const char *localFileName)
- { return decodeName(QByteArray(localFileName)); }
#if QT_DEPRECATED_SINCE(5,0)
typedef QByteArray (*EncoderFn)(const QString &fileName);
diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp
index ee619d99cc..b0aba3193c 100644
--- a/src/corelib/io/qfiledevice.cpp
+++ b/src/corelib/io/qfiledevice.cpp
@@ -202,7 +202,7 @@ QFileDevice::QFileDevice(QFileDevicePrivate &dd)
\internal
*/
QFileDevice::QFileDevice()
- : QIODevice(*new QFileDevicePrivate, 0)
+ : QIODevice(*new QFileDevicePrivate, nullptr)
{
}
/*!
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 89834de29f..3fe1aec41f 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -134,7 +134,7 @@ uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) cons
// extra syscall. Bundle detecton on Mac can be slow, expecially on network
// paths, so we separate out that as well.
- QAbstractFileEngine::FileFlags req = nullptr;
+ QAbstractFileEngine::FileFlags req;
uint cachedFlags = 0;
if (request & (QAbstractFileEngine::FlagsMask | QAbstractFileEngine::TypesMask)) {
@@ -1145,6 +1145,25 @@ bool QFileInfo::isShortcut() const
[d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); });
}
+
+/*!
+ Returns \c true if the object points to a junction;
+ otherwise returns \c false.
+
+ Junctions only exist on Windows' NTFS file system, and are typically
+ created by the \c{mklink} command. They can be thought of as symlinks for
+ directories, and can only be created for absolute paths on the local
+ volume.
+*/
+bool QFileInfo::isJunction() const
+{
+ Q_D(const QFileInfo);
+ return d->checkAttribute<bool>(
+ QFileSystemMetaData::LegacyLinkType,
+ [d]() { return d->metaData.isJunction(); },
+ [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); });
+}
+
/*!
Returns \c true if the object points to a directory or to a symbolic
link to a directory, and that directory is the root directory; otherwise
diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h
index 3ac028085a..7c7ff56ae4 100644
--- a/src/corelib/io/qfileinfo.h
+++ b/src/corelib/io/qfileinfo.h
@@ -113,6 +113,7 @@ public:
bool isSymLink() const;
bool isSymbolicLink() const;
bool isShortcut() const;
+ bool isJunction() const;
bool isRoot() const;
bool isBundle() const;
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index c3abec8989..3bbebc7fe9 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -55,7 +55,7 @@
#include <stdio.h>
#include <errno.h>
-#if QT_HAS_INCLUDE(<paths.h>)
+#if __has_include(<paths.h>)
# include <paths.h>
#endif
#ifndef _PATH_TMP // from <paths.h>
@@ -1076,14 +1076,14 @@ bool QFileSystemEngine::cloneFile(int srcfd, int dstfd, const QFileSystemMetaDat
// sendfile(2) is limited in the kernel to 2G - 4k
const size_t SendfileSize = 0x7ffff000;
- ssize_t n = ::sendfile(dstfd, srcfd, NULL, SendfileSize);
+ ssize_t n = ::sendfile(dstfd, srcfd, nullptr, SendfileSize);
if (n == -1) {
// if we got an error here, give up and try at an upper layer
return false;
}
while (n) {
- n = ::sendfile(dstfd, srcfd, NULL, SendfileSize);
+ n = ::sendfile(dstfd, srcfd, nullptr, SendfileSize);
if (n == -1) {
// uh oh, this is probably a real error (like ENOSPC), but we have
// no way to notify QFile of partial success, so just erase any work
diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h
index 81f4b3ba13..3154658e5c 100644
--- a/src/corelib/io/qfilesystemmetadata_p.h
+++ b/src/corelib/io/qfilesystemmetadata_p.h
@@ -76,8 +76,7 @@ class Q_AUTOTEST_EXPORT QFileSystemMetaData
{
public:
QFileSystemMetaData()
- : knownFlagsMask(nullptr),
- size_(-1)
+ : size_(-1)
{
}
@@ -111,8 +110,10 @@ public:
AliasType = 0x0,
#endif
#if defined(Q_OS_WIN)
+ JunctionType = 0x04000000,
WinLnkType = 0x08000000, // Note: Uses the same position for AliasType on Mac
#else
+ JunctionType = 0x0,
WinLnkType = 0x0,
#endif
SequentialType = 0x00800000, // Note: overlaps with QAbstractFileEngine::RootFlag
@@ -184,7 +185,7 @@ public:
void clear()
{
- knownFlagsMask = nullptr;
+ knownFlagsMask = {};
}
void clearFlags(MetaDataFlags flags = AllMetaDataFlags)
@@ -205,8 +206,10 @@ public:
bool wasDeleted() const { return (entryFlags & WasDeletedAttribute); }
#if defined(Q_OS_WIN)
bool isLnkFile() const { return (entryFlags & WinLnkType); }
+ bool isJunction() const { return (entryFlags & JunctionType); }
#else
bool isLnkFile() const { return false; }
+ bool isJunction() const { return false; }
#endif
qint64 size() const { return size_; }
@@ -356,9 +359,15 @@ inline void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, boo
if (setLinkType) {
knownFlagsMask |= LinkType;
entryFlags &= ~LinkType;
- if ((fileAttribute_ & FILE_ATTRIBUTE_REPARSE_POINT)
- && (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
- entryFlags |= LinkType;
+ if (fileAttribute_ & FILE_ATTRIBUTE_REPARSE_POINT) {
+ if (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
+ entryFlags |= LinkType;
+#if defined(IO_REPARSE_TAG_MOUNT_POINT)
+ } else if ((fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY)
+ && (findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)) {
+ entryFlags |= JunctionType;
+#endif
+ }
}
}
}
diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp
index 54460aff77..86c8963cb6 100644
--- a/src/corelib/io/qfilesystemwatcher.cpp
+++ b/src/corelib/io/qfilesystemwatcher.cpp
@@ -88,7 +88,7 @@ QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject
}
QFileSystemWatcherPrivate::QFileSystemWatcherPrivate()
- : native(0), poller(0)
+ : native(nullptr), poller(nullptr)
{
}
diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp
index ca1f6cc359..888af998a5 100644
--- a/src/corelib/io/qfilesystemwatcher_inotify.cpp
+++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp
@@ -242,7 +242,7 @@ QInotifyFileSystemWatcherEngine *QInotifyFileSystemWatcherEngine::create(QObject
if (fd == -1) {
fd = inotify_init();
if (fd == -1)
- return 0;
+ return nullptr;
}
return new QInotifyFileSystemWatcherEngine(fd, parent);
}
diff --git a/src/corelib/io/qfilesystemwatcher_win.cpp b/src/corelib/io/qfilesystemwatcher_win.cpp
index 1d42dbfc70..f955e3b53a 100644
--- a/src/corelib/io/qfilesystemwatcher_win.cpp
+++ b/src/corelib/io/qfilesystemwatcher_win.cpp
@@ -403,6 +403,7 @@ QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths,
const QString absolutePath = isDir ? fileInfo.absoluteFilePath() : fileInfo.absolutePath();
const uint flags = isDir
? (FILE_NOTIFY_CHANGE_DIR_NAME
+ | FILE_NOTIFY_CHANGE_ATTRIBUTES
| FILE_NOTIFY_CHANGE_FILE_NAME)
: (FILE_NOTIFY_CHANGE_DIR_NAME
| FILE_NOTIFY_CHANGE_FILE_NAME
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index 5b868cc447..dd4882a2bc 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -591,14 +591,14 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil
if (type & Refresh)
d->metaData.clear();
- QAbstractFileEngine::FileFlags ret = 0;
+ QAbstractFileEngine::FileFlags ret;
if (type & FlagsMask)
ret |= LocalDiskFlag;
bool exists;
{
- QFileSystemMetaData::MetaDataFlags queryFlags = 0;
+ QFileSystemMetaData::MetaDataFlags queryFlags;
queryFlags |= QFileSystemMetaData::MetaDataFlags(uint(type))
& QFileSystemMetaData::Permissions;
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index e26508e631..b89cab5e3c 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -461,7 +461,7 @@ QIODevice::QIODevice(QIODevicePrivate &dd)
*/
QIODevice::QIODevice()
- : QObject(*new QIODevicePrivate, 0)
+ : QObject(*new QIODevicePrivate, nullptr)
{
#if defined QIODEVICE_DEBUG
QFile *file = qobject_cast<QFile *>(this);
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index 4d4784cdf7..5de8be116c 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -179,7 +179,7 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
The \c QtProject/qtlogging.ini file is looked up in all directories returned
by QStandardPaths::GenericConfigLocation.
- Set the \c QT_LOGGING_DEBUG environment variable to find out where you logging
+ Set the \c QT_LOGGING_DEBUG environment variable to find out where your logging
rules are loaded from.
\section2 Installing a Custom Filter
diff --git a/src/corelib/io/qnoncontiguousbytedevice.cpp b/src/corelib/io/qnoncontiguousbytedevice.cpp
index d1806aa12b..df0197e8eb 100644
--- a/src/corelib/io/qnoncontiguousbytedevice.cpp
+++ b/src/corelib/io/qnoncontiguousbytedevice.cpp
@@ -127,7 +127,7 @@ QT_BEGIN_NAMESPACE
\internal
*/
-QNonContiguousByteDevice::QNonContiguousByteDevice() : QObject((QObject*)0)
+QNonContiguousByteDevice::QNonContiguousByteDevice() : QObject((QObject*)nullptr)
{
}
@@ -188,7 +188,7 @@ const char* QNonContiguousByteDeviceByteArrayImpl::readPointer(qint64 maximumLen
{
if (atEnd()) {
len = -1;
- return 0;
+ return nullptr;
}
if (maximumLength != -1)
@@ -241,7 +241,7 @@ const char* QNonContiguousByteDeviceRingBufferImpl::readPointer(qint64 maximumLe
{
if (atEnd()) {
len = -1;
- return 0;
+ return nullptr;
}
const char *returnValue = ringBuffer->readPointerAtPosition(currentPosition, len);
@@ -282,7 +282,7 @@ qint64 QNonContiguousByteDeviceRingBufferImpl::size() const
QNonContiguousByteDeviceIoDeviceImpl::QNonContiguousByteDeviceIoDeviceImpl(QIODevice *d)
: QNonContiguousByteDevice(),
- currentReadBuffer(0), currentReadBufferSize(16*1024),
+ currentReadBuffer(nullptr), currentReadBufferSize(16*1024),
currentReadBufferAmount(0), currentReadBufferPosition(0), totalAdvancements(0),
eof(false)
{
@@ -301,10 +301,10 @@ const char* QNonContiguousByteDeviceIoDeviceImpl::readPointer(qint64 maximumLeng
{
if (eof == true) {
len = -1;
- return 0;
+ return nullptr;
}
- if (currentReadBuffer == 0)
+ if (currentReadBuffer == nullptr)
currentReadBuffer = new QByteArray(currentReadBufferSize, '\0'); // lazy alloc
if (maximumLength == -1)
@@ -323,7 +323,7 @@ const char* QNonContiguousByteDeviceIoDeviceImpl::readPointer(qint64 maximumLeng
// size was unknown before, emit a readProgress with the final size
if (size() == -1)
emit readProgress(totalAdvancements, totalAdvancements);
- return 0;
+ return nullptr;
}
currentReadBufferAmount = haveRead;
@@ -349,7 +349,7 @@ bool QNonContiguousByteDeviceIoDeviceImpl::advanceReadPointer(qint64 amount)
if (currentReadBufferPosition > currentReadBufferAmount) {
qint64 i = currentReadBufferPosition - currentReadBufferAmount;
while (i > 0) {
- if (device->getChar(0) == false) {
+ if (device->getChar(nullptr) == false) {
emit readProgress(totalAdvancements - i, size());
return false; // ### FIXME handle eof
}
@@ -377,7 +377,7 @@ bool QNonContiguousByteDeviceIoDeviceImpl::reset()
totalAdvancements = 0; //reset the progress counter
if (currentReadBuffer) {
delete currentReadBuffer;
- currentReadBuffer = 0;
+ currentReadBuffer = nullptr;
}
currentReadBufferAmount = 0;
currentReadBufferPosition = 0;
@@ -405,7 +405,7 @@ qint64 QNonContiguousByteDeviceIoDeviceImpl::pos() const
return device->pos();
}
-QByteDeviceWrappingIoDevice::QByteDeviceWrappingIoDevice(QNonContiguousByteDevice *bd) : QIODevice((QObject*)0)
+QByteDeviceWrappingIoDevice::QByteDeviceWrappingIoDevice(QNonContiguousByteDevice *bd) : QIODevice((QObject*)nullptr)
{
byteDevice = bd;
connect(bd, SIGNAL(readyRead()), SIGNAL(readyRead()));
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 35ca2542f7..aedcae2cdc 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -100,7 +100,7 @@ QT_END_NAMESPACE
#include <private/qcore_unix_p.h>
#endif
-#if QT_HAS_INCLUDE(<paths.h>)
+#if __has_include(<paths.h>)
#include <paths.h>
#endif
@@ -216,7 +216,7 @@ void QProcessEnvironmentPrivate::insert(const QProcessEnvironmentPrivate &other)
environment variables to be removed.
*/
QProcessEnvironment::QProcessEnvironment()
- : d(0)
+ : d(nullptr)
{
}
@@ -436,18 +436,18 @@ void QProcessPrivate::Channel::clear()
case PipeSource:
Q_ASSERT(process);
process->stdinChannel.type = Normal;
- process->stdinChannel.process = 0;
+ process->stdinChannel.process = nullptr;
break;
case PipeSink:
Q_ASSERT(process);
process->stdoutChannel.type = Normal;
- process->stdoutChannel.process = 0;
+ process->stdoutChannel.process = nullptr;
break;
}
type = Normal;
file.clear();
- process = 0;
+ process = nullptr;
}
/*!
@@ -869,8 +869,8 @@ QProcessPrivate::QProcessPrivate()
sequenceNumber = 0;
exitCode = 0;
exitStatus = QProcess::NormalExit;
- startupSocketNotifier = 0;
- deathNotifier = 0;
+ startupSocketNotifier = nullptr;
+ deathNotifier = nullptr;
childStartedPipe[0] = INVALID_Q_PIPE;
childStartedPipe[1] = INVALID_Q_PIPE;
forkfd = -1;
@@ -924,23 +924,23 @@ void QProcessPrivate::cleanup()
if (stdoutChannel.notifier) {
delete stdoutChannel.notifier;
- stdoutChannel.notifier = 0;
+ stdoutChannel.notifier = nullptr;
}
if (stderrChannel.notifier) {
delete stderrChannel.notifier;
- stderrChannel.notifier = 0;
+ stderrChannel.notifier = nullptr;
}
if (stdinChannel.notifier) {
delete stdinChannel.notifier;
- stdinChannel.notifier = 0;
+ stdinChannel.notifier = nullptr;
}
if (startupSocketNotifier) {
delete startupSocketNotifier;
- startupSocketNotifier = 0;
+ startupSocketNotifier = nullptr;
}
if (deathNotifier) {
delete deathNotifier;
- deathNotifier = 0;
+ deathNotifier = nullptr;
}
closeChannel(&stdoutChannel);
closeChannel(&stderrChannel);
@@ -1004,7 +1004,7 @@ QT_WARNING_POP
/*!
\internal
- Returns true if we emitted readyRead().
+ Returns \c true if we emitted readyRead().
*/
bool QProcessPrivate::tryReadFromChannel(Channel *channel)
{
@@ -1229,7 +1229,7 @@ void QProcessPrivate::closeWriteChannel()
#endif
if (stdinChannel.notifier) {
delete stdinChannel.notifier;
- stdinChannel.notifier = 0;
+ stdinChannel.notifier = nullptr;
}
#ifdef Q_OS_WIN
// ### Find a better fix, feeding the process little by little
@@ -2187,6 +2187,8 @@ bool QProcess::startDetached(qint64 *pid)
This method is an alias for start(), and exists only to fully implement
the interface defined by QIODevice.
+ Returns \c true if the program has been started.
+
\sa start(), setProgram(), setArguments()
*/
bool QProcess::open(OpenMode mode)
@@ -2615,7 +2617,7 @@ QT_END_INCLUDE_NAMESPACE
QStringList QProcess::systemEnvironment()
{
QStringList tmp;
- char *entry = 0;
+ char *entry = nullptr;
int count = 0;
while ((entry = environ[count++]))
tmp << QString::fromLocal8Bit(entry);
diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h
index 9fda5fba11..585508adf1 100644
--- a/src/corelib/io/qprocess.h
+++ b/src/corelib/io/qprocess.h
@@ -278,7 +278,8 @@ Q_SIGNALS:
void finished(int exitCode); // ### Qt 6: merge the two signals with a default value
#endif
void finished(int exitCode, QProcess::ExitStatus exitStatus);
-#if QT_DEPRECATED_SINCE(5,6)
+#if QT_DEPRECATED_SINCE(5, 6)
+ QT_DEPRECATED_X("Use QProcess::errorOccurred(QProcess::ProcessError) instead")
void error(QProcess::ProcessError error);
#endif
void errorOccurred(QProcess::ProcessError error);
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 0c80daa024..2186f23ab6 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -246,7 +246,7 @@ bool QProcessPrivate::openChannel(Channel &channel)
return false;
// create the socket notifiers
- if (threadData->hasEventDispatcher()) {
+ if (threadData.loadRelaxed()->hasEventDispatcher()) {
if (&channel == &stdinChannel) {
channel.notifier = new QSocketNotifier(channel.pipe[1],
QSocketNotifier::Write, q);
@@ -338,11 +338,11 @@ static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Map &environme
{
*envc = 0;
if (environment.isEmpty())
- return 0;
+ return nullptr;
char **envp = new char *[environment.count() + 2];
- envp[environment.count()] = 0;
- envp[environment.count() + 1] = 0;
+ envp[environment.count()] = nullptr;
+ envp[environment.count() + 1] = nullptr;
auto it = environment.constBegin();
const auto end = environment.constEnd();
@@ -377,7 +377,7 @@ void QProcessPrivate::startProcess()
return;
}
- if (threadData->hasEventDispatcher()) {
+ if (threadData.loadRelaxed()->hasEventDispatcher()) {
startupSocketNotifier = new QSocketNotifier(childStartedPipe[0],
QSocketNotifier::Read, q);
QObject::connect(startupSocketNotifier, SIGNAL(activated(int)),
@@ -390,7 +390,7 @@ void QProcessPrivate::startProcess()
// Create argument list with right number of elements, and set the final
// one to 0.
char **argv = new char *[arguments.count() + 2];
- argv[arguments.count() + 1] = 0;
+ argv[arguments.count() + 1] = nullptr;
// Encode the program name.
QByteArray encodedProgramName = QFile::encodeName(program);
@@ -437,13 +437,13 @@ void QProcessPrivate::startProcess()
// Duplicate the environment.
int envc = 0;
- char **envp = 0;
+ char **envp = nullptr;
if (environment.d.constData()) {
envp = _q_dupEnvironment(environment.d.constData()->vars, &envc);
}
// Encode the working directory if it's non-empty, otherwise just pass 0.
- const char *workingDirPtr = 0;
+ const char *workingDirPtr = nullptr;
QByteArray encodedWorkingDirectory;
if (!workingDirectory.isEmpty()) {
encodedWorkingDirectory = QFile::encodeName(workingDirectory);
@@ -451,8 +451,13 @@ void QProcessPrivate::startProcess()
}
// Start the process manager, and fork off the child process.
+ // ### Qt6: revisit whether the change in behavior due to not using fork()
+ // is acceptable for derived classes.
+ int ffdflags = FFD_CLOEXEC;
+ if (typeid(*q) != typeid(QProcess))
+ ffdflags |= FFD_USE_FORK;
pid_t childPid;
- forkfd = ::forkfd(FFD_CLOEXEC, &childPid);
+ forkfd = ::forkfd(ffdflags , &childPid);
int lastForkErrno = errno;
if (forkfd != FFD_CHILD_PROCESS) {
// Parent process.
@@ -517,7 +522,7 @@ void QProcessPrivate::startProcess()
if (stderrChannel.pipe[0] != -1)
::fcntl(stderrChannel.pipe[0], F_SETFL, ::fcntl(stderrChannel.pipe[0], F_GETFL) | O_NONBLOCK);
- if (threadData->eventDispatcher.loadAcquire()) {
+ if (threadData.loadRelaxed()->eventDispatcher.loadAcquire()) {
deathNotifier = new QSocketNotifier(forkfd, QSocketNotifier::Read, q);
QObject::connect(deathNotifier, SIGNAL(activated(int)),
q, SLOT(_q_processDied()));
@@ -596,7 +601,7 @@ bool QProcessPrivate::processStarted(QString *errorMessage)
if (startupSocketNotifier) {
startupSocketNotifier->setEnabled(false);
startupSocketNotifier->deleteLater();
- startupSocketNotifier = 0;
+ startupSocketNotifier = nullptr;
}
qt_safe_close(childStartedPipe[0]);
childStartedPipe[0] = -1;
@@ -889,7 +894,7 @@ bool QProcessPrivate::waitForDeadChild()
crashed = info.code != CLD_EXITED;
delete deathNotifier;
- deathNotifier = 0;
+ deathNotifier = nullptr;
EINTR_LOOP(ret, forkfd_close(forkfd));
forkfd = -1; // Child is dead, don't try to kill it anymore
@@ -935,7 +940,7 @@ bool QProcessPrivate::startDetached(qint64 *pid)
struct sigaction noaction;
memset(&noaction, 0, sizeof(noaction));
noaction.sa_handler = SIG_IGN;
- ::sigaction(SIGPIPE, &noaction, 0);
+ ::sigaction(SIGPIPE, &noaction, nullptr);
::setsid();
@@ -964,7 +969,7 @@ bool QProcessPrivate::startDetached(qint64 *pid)
char **argv = new char *[arguments.size() + 2];
for (int i = 0; i < arguments.size(); ++i)
argv[i + 1] = ::strdup(QFile::encodeName(arguments.at(i)).constData());
- argv[arguments.size() + 1] = 0;
+ argv[arguments.size() + 1] = nullptr;
// Duplicate the environment.
int envc = 0;
@@ -991,7 +996,7 @@ bool QProcessPrivate::startDetached(qint64 *pid)
struct sigaction noaction;
memset(&noaction, 0, sizeof(noaction));
noaction.sa_handler = SIG_IGN;
- ::sigaction(SIGPIPE, &noaction, 0);
+ ::sigaction(SIGPIPE, &noaction, nullptr);
// '\1' means execv failed
char c = '\1';
@@ -1002,7 +1007,7 @@ bool QProcessPrivate::startDetached(qint64 *pid)
struct sigaction noaction;
memset(&noaction, 0, sizeof(noaction));
noaction.sa_handler = SIG_IGN;
- ::sigaction(SIGPIPE, &noaction, 0);
+ ::sigaction(SIGPIPE, &noaction, nullptr);
// '\2' means internal error
char c = '\2';
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index 3ba86063e3..1527cf93ed 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -49,7 +49,6 @@
#include <qelapsedtimer.h>
#include <qfileinfo.h>
#include <qrandom.h>
-#include <qregexp.h>
#include <qwineventnotifier.h>
#include <private/qsystemlibrary_p.h>
#include <private/qthread_p.h>
@@ -398,7 +397,17 @@ static QString qt_create_commandline(const QString &program, const QStringList &
for (int i=0; i<arguments.size(); ++i) {
QString tmp = arguments.at(i);
// Quotes are escaped and their preceding backslashes are doubled.
- tmp.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\\1\\1\\\""));
+ int index = tmp.indexOf(QLatin1Char('"'));
+ while (index >= 0) {
+ // Escape quote
+ tmp.insert(index++, QLatin1Char('\\'));
+ // Double preceding backslashes (ignoring the one we just inserted)
+ for (int i = index - 2 ; i >= 0 && tmp.at(i) == QLatin1Char('\\') ; --i) {
+ tmp.insert(i, QLatin1Char('\\'));
+ index++;
+ }
+ index = tmp.indexOf(QLatin1Char('"'), index + 1);
+ }
if (tmp.isEmpty() || tmp.contains(QLatin1Char(' ')) || tmp.contains(QLatin1Char('\t'))) {
// The argument must not end with a \ since this would be interpreted
// as escaping the quote -- rather put the \ behind the quote: e.g.
@@ -590,7 +599,7 @@ void QProcessPrivate::startProcess()
if (!pid)
return;
- if (threadData->hasEventDispatcher()) {
+ if (threadData.loadRelaxed()->hasEventDispatcher()) {
processFinishedNotifier = new QWinEventNotifier(pid->hProcess, q);
QObject::connect(processFinishedNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_processDied()));
processFinishedNotifier->setEnabled(true);
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index 86d361b06a..e636712e57 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Copyright (C) 2019 Intel Corporation.
+** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2020 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -60,14 +60,14 @@
#include "private/qtools_p.h"
#include "private/qsystemerror_p.h"
+#ifndef QT_NO_COMPRESS
+# include <zconf.h>
+# include <zlib.h>
+#endif
#if QT_CONFIG(zstd)
# include <zstd.h>
#endif
-#ifdef Q_OS_UNIX
-# include "private/qcore_unix_p.h"
-#endif
-
#if defined(Q_OS_UNIX) && !defined(Q_OS_NACL) && !defined(Q_OS_INTEGRITY)
# define QT_USE_MMAP
# include <sys/mman.h>
@@ -280,9 +280,9 @@ static inline QStringList *resourceSearchPaths()
RCC tool used to compress the payload.
\value NoCompression Contents are not compressed
- \value ZlibCompression Contents are compressed using \l{zlib}{https://zlib.net} and can
+ \value ZlibCompression Contents are compressed using \l{https://zlib.net}{zlib} and can
be decompressed using the qUncompress() function.
- \value ZstdCompression Contents are compressed using \l{zstd}{https://zstd.net}. To
+ \value ZstdCompression Contents are compressed using \l{https://zstd.net}{zstd}. To
decompress, use the \c{ZSTD_decompress} function from the zstd
library.
@@ -296,6 +296,8 @@ public:
void ensureInitialized() const;
void ensureChildren() const;
+ qint64 uncompressedSize() const Q_DECL_PURE_FUNCTION;
+ qsizetype decompress(char *buffer, qsizetype bufferSize) const;
bool load(const QString &file);
void clear();
@@ -440,6 +442,78 @@ QResourcePrivate::ensureChildren() const
}
}
+qint64 QResourcePrivate::uncompressedSize() const
+{
+ switch (compressionAlgo) {
+ case QResource::NoCompression:
+ return size;
+
+ case QResource::ZlibCompression:
+#ifndef QT_NO_COMPRESS
+ if (size_t(size) >= sizeof(quint32))
+ return qFromBigEndian<quint32>(data);
+#else
+ Q_ASSERT(!"QResource: Qt built without support for Zlib compression");
+ Q_UNREACHABLE();
+#endif
+ break;
+
+ case QResource::ZstdCompression: {
+#if QT_CONFIG(zstd)
+ size_t n = ZSTD_getFrameContentSize(data, size);
+ return ZSTD_isError(n) ? -1 : qint64(n);
+#else
+ // This should not happen because we've refused to load such resource
+ Q_ASSERT(!"QResource: Qt built without support for Zstd compression");
+ Q_UNREACHABLE();
+#endif
+ }
+
+ }
+ return -1;
+}
+
+qsizetype QResourcePrivate::decompress(char *buffer, qsizetype bufferSize) const
+{
+ Q_ASSERT(data);
+
+ switch (compressionAlgo) {
+ case QResource::NoCompression:
+ Q_UNREACHABLE();
+ break;
+
+ case QResource::ZlibCompression: {
+#ifndef QT_NO_COMPRESS
+ uLong len = uLong(bufferSize);
+ int res = ::uncompress(reinterpret_cast<Bytef *>(buffer), &len,
+ data + sizeof(quint32), uLong(size - sizeof(quint32)));
+ if (res != Z_OK) {
+ qWarning("QResource: error decompressing zlib content (%d)", res);
+ return -1;
+ }
+ return len;
+#else
+ Q_UNREACHABLE();
+#endif
+ }
+
+ case QResource::ZstdCompression: {
+#if QT_CONFIG(zstd)
+ size_t usize = ZSTD_decompress(buffer, bufferSize, data, size);
+ if (ZSTD_isError(usize)) {
+ qWarning("QResource: error decompressing zstd content: %s", ZSTD_getErrorName(usize));
+ return -1;
+ }
+ return usize;
+#else
+ Q_UNREACHABLE();
+#endif
+ }
+ }
+
+ return -1;
+}
+
/*!
Constructs a QResource pointing to \a file. \a locale is used to
load a specific localization of a resource data.
@@ -600,9 +674,12 @@ QResource::Compression QResource::compressionAlgorithm() const
}
/*!
- Returns the size of the data backing the resource.
+ Returns the size of the stored data backing the resource.
- \sa data(), isFile()
+ If the resource is compressed, this function returns the size of the
+ compressed data. See uncompressedSize() for the uncompressed size.
+
+ \sa data(), uncompressedSize(), isFile()
*/
qint64 QResource::size() const
@@ -613,12 +690,29 @@ qint64 QResource::size() const
}
/*!
- Returns direct access to a read only segment of data that this resource
- represents. If the resource is compressed the data returned is compressed
- and the appropriate library functions must be used to access the data. If
- the resource is a directory \nullptr is returned.
+ \since 5.15
+
+ Returns the size of the data in this resource. If the data was not
+ compressed, this function returns the same as size(). If it was, then this
+ function extracts the size of the original uncompressed data from the
+ stored stream.
- \sa size(), compressionAlgorithm(), isFile()
+ \sa size(), uncompressedData(), isFile()
+*/
+qint64 QResource::uncompressedSize() const
+{
+ Q_D(const QResource);
+ d->ensureInitialized();
+ return d->uncompressedSize();
+}
+
+/*!
+ Returns direct access to a segment of read-only data, that this resource
+ represents. If the resource is compressed, the data returned is also
+ compressed. The caller must then decompress the data or use
+ uncompressedData(). If the resource is a directory, \c nullptr is returned.
+
+ \sa uncompressedData(), size(), isFile()
*/
const uchar *QResource::data() const
@@ -629,6 +723,44 @@ const uchar *QResource::data() const
}
/*!
+ \since 5.15
+
+ Returns the resource data, decompressing it first, if the data was stored
+ compressed. If the resource is a directory or an error occurs while
+ decompressing, a null QByteArray is returned.
+
+ \note If the data was compressed, this function will decompress every time
+ it is called. The result is not cached between calls.
+
+ \sa uncompressedData(), size(), isCompressed(), isFile()
+*/
+
+QByteArray QResource::uncompressedData() const
+{
+ Q_D(const QResource);
+ qint64 n = uncompressedSize();
+ if (n < 0)
+ return QByteArray();
+ if (n > std::numeric_limits<QByteArray::size_type>::max()) {
+ qWarning("QResource: compressed content does not fit into a QByteArray; use QFile instead");
+ return QByteArray();
+ }
+ if (d->compressionAlgo == NoCompression)
+ return QByteArray::fromRawData(reinterpret_cast<const char *>(d->data), n);
+
+ // decompress
+ QByteArray result(n, Qt::Uninitialized);
+ n = d->decompress(result.data(), n);
+ if (n < 0)
+ result.clear();
+ else
+ result.truncate(n);
+ return result;
+}
+
+/*!
+ \since 5.8
+
Returns the date and time when the file was last modified before
packaging into a resource.
*/
@@ -1443,13 +1575,7 @@ bool QResourceFileEngine::link(const QString &)
qint64 QResourceFileEngine::size() const
{
Q_D(const QResourceFileEngine);
- if (!d->resource.isValid())
- return 0;
- if (d->resource.compressionAlgorithm() != QResource::NoCompression) {
- d->uncompress();
- return d->uncompressed.size();
- }
- return d->resource.size();
+ return d->resource.isValid() ? d->resource.uncompressedSize() : 0;
}
qint64 QResourceFileEngine::pos() const
@@ -1486,7 +1612,7 @@ bool QResourceFileEngine::isSequential() const
QAbstractFileEngine::FileFlags QResourceFileEngine::fileFlags(QAbstractFileEngine::FileFlags type) const
{
Q_D(const QResourceFileEngine);
- QAbstractFileEngine::FileFlags ret = 0;
+ QAbstractFileEngine::FileFlags ret;
if(!d->resource.isValid())
return ret;
@@ -1578,7 +1704,7 @@ QAbstractFileEngine::Iterator *QResourceFileEngine::beginEntryList(QDir::Filters
*/
QAbstractFileEngine::Iterator *QResourceFileEngine::endEntryList()
{
- return 0;
+ return nullptr;
}
bool QResourceFileEngine::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output)
@@ -1588,7 +1714,7 @@ bool QResourceFileEngine::extension(Extension extension, const ExtensionOption *
const MapExtensionOption *options = (const MapExtensionOption*)(option);
MapExtensionReturn *returnValue = static_cast<MapExtensionReturn*>(output);
returnValue->address = d->map(options->offset, options->size, options->flags);
- return (returnValue->address != 0);
+ return (returnValue->address != nullptr);
}
if (extension == UnMapExtension) {
const UnMapExtensionOption *options = (const UnMapExtensionOption*)option;
@@ -1607,22 +1733,21 @@ uchar *QResourceFileEnginePrivate::map(qint64 offset, qint64 size, QFile::Memory
Q_Q(QResourceFileEngine);
Q_UNUSED(flags);
- qint64 max = resource.size();
- if (resource.compressionAlgorithm() != QResource::NoCompression) {
- uncompress();
- max = uncompressed.size();
- }
-
+ qint64 max = resource.uncompressedSize();
qint64 end;
if (offset < 0 || size <= 0 || !resource.isValid() ||
add_overflow(offset, size, &end) || end > max) {
q->setError(QFile::UnspecifiedError, QString());
- return 0;
+ return nullptr;
}
const uchar *address = resource.data();
- if (resource.compressionAlgorithm() != QResource::NoCompression)
+ if (resource.compressionAlgorithm() != QResource::NoCompression) {
+ uncompress();
+ if (uncompressed.isNull())
+ return nullptr;
address = reinterpret_cast<const uchar *>(uncompressed.constData());
+ }
return const_cast<uchar *>(address) + offset;
}
@@ -1635,41 +1760,10 @@ bool QResourceFileEnginePrivate::unmap(uchar *ptr)
void QResourceFileEnginePrivate::uncompress() const
{
- if (uncompressed.isEmpty() && resource.size()) {
- quint64 size;
- switch (resource.compressionAlgorithm()) {
- case QResource::NoCompression:
- return; // nothing to do
-
- case QResource::ZlibCompression:
-#ifndef QT_NO_COMPRESS
- uncompressed = qUncompress(resource.data(), resource.size());
-#else
- Q_ASSERT(!"QResourceFileEngine::open: Qt built without support for Zlib compression");
-#endif
- break;
-
- case QResource::ZstdCompression:
-#if QT_CONFIG(zstd)
- size = ZSTD_getFrameContentSize(resource.data(), resource.size());
- if (!ZSTD_isError(size)) {
- if (size >= MaxAllocSize) {
- qWarning("QResourceFileEngine::open: content bigger than memory (size %lld)", size);
- } else {
- uncompressed = QByteArray(size, Qt::Uninitialized);
- size = ZSTD_decompress(const_cast<char *>(uncompressed.data()), size,
- resource.data(), resource.size());
- }
- }
- if (ZSTD_isError(size))
- qWarning("QResourceFileEngine::open: error decoding: %s", ZSTD_getErrorName(size));
-#else
- Q_UNUSED(size);
- Q_ASSERT(!"QResourceFileEngine::open: Qt built without support for Zstd compression");
-#endif
- break;
- }
- }
+ if (resource.compressionAlgorithm() == QResource::NoCompression
+ || !uncompressed.isEmpty() || resource.size() == 0)
+ return; // nothing to do
+ uncompressed = resource.uncompressedData();
}
#endif // !defined(QT_BOOTSTRAPPED)
diff --git a/src/corelib/io/qresource.h b/src/corelib/io/qresource.h
index 5ee8d5d266..52b0d74d29 100644
--- a/src/corelib/io/qresource.h
+++ b/src/corelib/io/qresource.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2019 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -75,6 +76,8 @@ public:
Compression compressionAlgorithm() const;
qint64 size() const;
const uchar *data() const;
+ qint64 uncompressedSize() const;
+ QByteArray uncompressedData() const;
QDateTime lastModified() const;
#if QT_DEPRECATED_SINCE(5, 13)
diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp
index 0a884a7df9..067ccda3df 100644
--- a/src/corelib/io/qsavefile.cpp
+++ b/src/corelib/io/qsavefile.cpp
@@ -116,7 +116,7 @@ QSaveFile::QSaveFile(const QString &name)
Constructs a new file object to represent the file with the given \a name.
*/
QSaveFile::QSaveFile(const QString &name)
- : QFileDevice(*new QSaveFilePrivate, 0)
+ : QFileDevice(*new QSaveFilePrivate, nullptr)
{
Q_D(QSaveFile);
d->fileName = name;
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index e485310e86..779b6f72de 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -76,10 +76,6 @@
# include <ioLib.h>
#endif
-#ifdef Q_OS_WASM
-#include <emscripten.h>
-#endif
-
#include <algorithm>
#include <stdlib.h>
@@ -210,7 +206,7 @@ QConfFile *QConfFile::fromName(const QString &fileName, bool _userPerms)
ConfFileHash *usedHash = usedHashFunc();
ConfFileCache *unusedCache = unusedCacheFunc();
- QConfFile *confFile = 0;
+ QConfFile *confFile = nullptr;
const auto locker = qt_scoped_lock(settingsGlobalMutex);
if (!(confFile = usedHash->value(absPath))) {
@@ -234,7 +230,7 @@ void QConfFile::clearCache()
// QSettingsPrivate
QSettingsPrivate::QSettingsPrivate(QSettings::Format format)
- : format(format), scope(QSettings::UserScope /* nothing better to put */), iniCodec(0), fallbacks(true),
+ : format(format), scope(QSettings::UserScope /* nothing better to put */), iniCodec(nullptr), fallbacks(true),
pendingChanges(false), status(QSettings::NoError)
{
}
@@ -242,7 +238,7 @@ QSettingsPrivate::QSettingsPrivate(QSettings::Format format)
QSettingsPrivate::QSettingsPrivate(QSettings::Format format, QSettings::Scope scope,
const QString &organization, const QString &application)
: format(format), scope(scope), organizationName(organization), applicationName(application),
- iniCodec(0), fallbacks(true), pendingChanges(false), status(QSettings::NoError)
+ iniCodec(nullptr), fallbacks(true), pendingChanges(false), status(QSettings::NoError)
{
}
@@ -295,7 +291,7 @@ after_loop:
// see also qsettings_win.cpp, qsettings_winrt.cpp and qsettings_mac.cpp
-#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
+#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC) && !defined(Q_OS_WASM)
QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::Scope scope,
const QString &organization, const QString &application)
{
@@ -931,8 +927,8 @@ QStringList QSettingsPrivate::splitArgs(const QString &s, int idx)
void QConfFileSettingsPrivate::initFormat()
{
extension = (format == QSettings::NativeFormat) ? QLatin1String(".conf") : QLatin1String(".ini");
- readFunc = 0;
- writeFunc = 0;
+ readFunc = nullptr;
+ writeFunc = nullptr;
#if defined(Q_OS_MAC)
caseSensitivity = (format == QSettings::NativeFormat) ? Qt::CaseSensitive : IniCaseSensitivity;
#else
@@ -1188,7 +1184,9 @@ QConfFileSettingsPrivate::QConfFileSettingsPrivate(QSettings::Format format,
confFiles.append(QConfFile::fromName(systemPath.path + orgFile, false));
}
+#ifndef Q_OS_WASM // wasm needs to delay access until after file sync
initAccess();
+#endif
}
QConfFileSettingsPrivate::QConfFileSettingsPrivate(const QString &fileName,
@@ -1551,13 +1549,6 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile)
perms |= QFile::ReadGroup | QFile::ReadOther;
QFile(confFile->name).setPermissions(perms);
}
-#ifdef Q_OS_WASM
- EM_ASM(
- // Sync sandbox filesystem to persistent database filesystem. See QTBUG-70002
- FS.syncfs(false, function(err) {
- });
- );
-#endif
} else {
setStatus(QSettings::AccessError);
}
@@ -3350,7 +3341,7 @@ bool QSettings::contains(const QString &key) const
{
Q_D(const QSettings);
QString k = d->actualKey(key);
- return d->get(k, 0);
+ return d->get(k, nullptr);
}
/*!
diff --git a/src/corelib/io/qsettings_p.h b/src/corelib/io/qsettings_p.h
index d18c96a06c..c30f099a72 100644
--- a/src/corelib/io/qsettings_p.h
+++ b/src/corelib/io/qsettings_p.h
@@ -57,6 +57,10 @@
#include "QtCore/qiodevice.h"
#include "QtCore/qstack.h"
#include "QtCore/qstringlist.h"
+
+#include <QtCore/qvariant.h>
+#include "qsettings.h"
+
#ifndef QT_NO_QOBJECT
#include "private/qobject_p.h"
#endif
@@ -253,6 +257,10 @@ protected:
mutable QSettings::Status status;
};
+#ifdef Q_OS_WASM
+class QWasmSettingsPrivate;
+#endif
+
class QConfFileSettingsPrivate : public QSettingsPrivate
{
public:
@@ -281,7 +289,7 @@ public:
private:
void initFormat();
- void initAccess();
+ virtual void initAccess();
void syncConfFile(QConfFile *confFile);
bool writeIniFile(QIODevice &device, const ParsedSettingsMap &map);
#ifdef Q_OS_MAC
@@ -297,6 +305,9 @@ private:
QString extension;
Qt::CaseSensitivity caseSensitivity;
int nextPosition;
+#ifdef Q_OS_WASM
+ friend class QWasmSettingsPrivate;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/corelib/io/qsettings_wasm.cpp b/src/corelib/io/qsettings_wasm.cpp
new file mode 100644
index 0000000000..8d8f4b505c
--- /dev/null
+++ b/src/corelib/io/qsettings_wasm.cpp
@@ -0,0 +1,259 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsettings.h"
+#ifndef QT_NO_SETTINGS
+
+#include "qsettings_p.h"
+#ifndef QT_NO_QOBJECT
+#include "qcoreapplication.h"
+#include <QFile>
+#endif // QT_NO_QOBJECT
+#include <QDebug>
+
+#include <QFileInfo>
+#include <QDir>
+#include <emscripten.h>
+
+QT_BEGIN_NAMESPACE
+
+static bool isReadReady = false;
+
+class QWasmSettingsPrivate : public QConfFileSettingsPrivate
+{
+public:
+ QWasmSettingsPrivate(QSettings::Scope scope, const QString &organization,
+ const QString &application);
+ ~QWasmSettingsPrivate();
+
+ bool get(const QString &key, QVariant *value) const override;
+ QStringList children(const QString &prefix, ChildSpec spec) const override;
+ void clear() override;
+ void sync() override;
+ void flush() override;
+ bool isWritable() const override;
+
+ void syncToLocal(const char *data, int size);
+ void loadLocal(const QByteArray &filename);
+ void setReady();
+ void initAccess() override;
+
+private:
+ QString databaseName;
+ QString id;
+};
+
+static void QWasmSettingsPrivate_onLoad(void *userData, void *dataPtr, int size)
+{
+ QWasmSettingsPrivate *wasm = reinterpret_cast<QWasmSettingsPrivate *>(userData);
+
+ QFile file(wasm->fileName());
+ QFileInfo fileInfo(wasm->fileName());
+ QDir dir(fileInfo.path());
+ if (!dir.exists())
+ dir.mkpath(fileInfo.path());
+
+ if (file.open(QFile::WriteOnly)) {
+ file.write(reinterpret_cast<char *>(dataPtr), size);
+ file.close();
+ wasm->setReady();
+ }
+}
+
+static void QWasmSettingsPrivate_onError(void *userData)
+{
+ QWasmSettingsPrivate *wasm = reinterpret_cast<QWasmSettingsPrivate *>(userData);
+ if (wasm)
+ wasm->setStatus(QSettings::AccessError);
+}
+
+static void QWasmSettingsPrivate_onStore(void *userData)
+{
+ QWasmSettingsPrivate *wasm = reinterpret_cast<QWasmSettingsPrivate *>(userData);
+ if (wasm)
+ wasm->setStatus(QSettings::NoError);
+}
+
+static void QWasmSettingsPrivate_onCheck(void *userData, int exists)
+{
+ QWasmSettingsPrivate *wasm = reinterpret_cast<QWasmSettingsPrivate *>(userData);
+ if (wasm) {
+ if (exists)
+ wasm->loadLocal(wasm->fileName().toLocal8Bit());
+ else
+ wasm->setReady();
+ }
+}
+
+QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format,
+ QSettings::Scope scope,
+ const QString &organization,
+ const QString &application)
+{
+ Q_UNUSED(format)
+ if (organization == QLatin1String("Qt"))
+ {
+ QString organizationDomain = QCoreApplication::organizationDomain();
+ QString applicationName = QCoreApplication::applicationName();
+
+ QSettingsPrivate *newSettings;
+ newSettings = new QWasmSettingsPrivate(scope, organizationDomain, applicationName);
+
+ newSettings->beginGroupOrArray(QSettingsGroup(normalizedKey(organization)));
+ if (!application.isEmpty())
+ newSettings->beginGroupOrArray(QSettingsGroup(normalizedKey(application)));
+
+ return newSettings;
+ }
+ return new QWasmSettingsPrivate(scope, organization, application);
+}
+
+QWasmSettingsPrivate::QWasmSettingsPrivate(QSettings::Scope scope, const QString &organization,
+ const QString &application)
+ : QConfFileSettingsPrivate(QSettings::NativeFormat, scope, organization, application)
+{
+ setStatus(QSettings::AccessError); // access error until sandbox gets loaded
+ databaseName = organization;
+ id = application;
+
+ emscripten_idb_async_exists("/home/web_user",
+ fileName().toLocal8Bit(),
+ reinterpret_cast<void*>(this),
+ QWasmSettingsPrivate_onCheck,
+ QWasmSettingsPrivate_onError);
+}
+
+QWasmSettingsPrivate::~QWasmSettingsPrivate()
+{
+}
+
+ void QWasmSettingsPrivate::initAccess()
+{
+ if (isReadReady)
+ QConfFileSettingsPrivate::initAccess();
+}
+
+bool QWasmSettingsPrivate::get(const QString &key, QVariant *value) const
+{
+ if (isReadReady)
+ return QConfFileSettingsPrivate::get(key, value);
+
+ return false;
+}
+
+QStringList QWasmSettingsPrivate::children(const QString &prefix, ChildSpec spec) const
+{
+ return QConfFileSettingsPrivate::children(prefix, spec);
+}
+
+void QWasmSettingsPrivate::clear()
+{
+ QConfFileSettingsPrivate::clear();
+ emscripten_idb_async_delete("/home/web_user",
+ fileName().toLocal8Bit(),
+ reinterpret_cast<void*>(this),
+ QWasmSettingsPrivate_onStore,
+ QWasmSettingsPrivate_onError);
+}
+
+void QWasmSettingsPrivate::sync()
+{
+ QConfFileSettingsPrivate::sync();
+
+ QFile file(fileName());
+ if (file.open(QFile::ReadOnly)) {
+ QByteArray dataPointer = file.readAll();
+
+ emscripten_idb_async_store("/home/web_user",
+ fileName().toLocal8Bit(),
+ reinterpret_cast<void *>(dataPointer.data()),
+ dataPointer.length(),
+ reinterpret_cast<void*>(this),
+ QWasmSettingsPrivate_onStore,
+ QWasmSettingsPrivate_onError);
+ }
+}
+
+void QWasmSettingsPrivate::flush()
+{
+ sync();
+}
+
+bool QWasmSettingsPrivate::isWritable() const
+{
+ return isReadReady && QConfFileSettingsPrivate::isWritable();
+}
+
+void QWasmSettingsPrivate::syncToLocal(const char *data, int size)
+{
+ QFile file(fileName());
+
+ if (file.open(QFile::WriteOnly)) {
+ file.write(data, size + 1);
+ QByteArray data = file.readAll();
+
+ emscripten_idb_async_store("/home/web_user",
+ fileName().toLocal8Bit(),
+ reinterpret_cast<void *>(data.data()),
+ data.length(),
+ reinterpret_cast<void*>(this),
+ QWasmSettingsPrivate_onStore,
+ QWasmSettingsPrivate_onError);
+ setReady();
+ }
+}
+
+void QWasmSettingsPrivate::loadLocal(const QByteArray &filename)
+{
+ emscripten_idb_async_load("/home/web_user",
+ filename.data(),
+ reinterpret_cast<void*>(this),
+ QWasmSettingsPrivate_onLoad,
+ QWasmSettingsPrivate_onError);
+}
+
+void QWasmSettingsPrivate::setReady()
+{
+ isReadReady = true;
+ setStatus(QSettings::NoError);
+ QConfFileSettingsPrivate::initAccess();
+}
+
+QT_END_NAMESPACE
+#endif // QT_NO_SETTINGS
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index 7874b854e4..a5128a868b 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -48,7 +48,7 @@
#include <qcoreapplication.h>
#endif
-#if QT_HAS_INCLUDE(<paths.h>)
+#if __has_include(<paths.h>)
#include <paths.h>
#endif
@@ -359,22 +359,14 @@ QT_BEGIN_NAMESPACE
/*!
\fn QString QStandardPaths::writableLocation(StandardLocation type)
- Returns the directory where files of \a type should be written to, or an empty string
- if the location cannot be determined.
-
- \note The storage location returned can be a directory that does not exist; i.e., it
- may need to be created by the system or the user.
+ \include standardpath/functiondocs.qdocinc writableLocation
*/
/*!
\fn QStringList QStandardPaths::standardLocations(StandardLocation type)
- Returns all the directories where files of \a type belong.
-
- The list of directories is sorted from high to low priority, starting with
- writableLocation() if it can be determined. This list is empty if no locations
- for \a type are defined.
+ \include standardpath/functiondocs.qdocinc standardLocations
\sa writableLocation()
*/
@@ -398,11 +390,7 @@ static bool existsAsSpecified(const QString &path, QStandardPaths::LocateOptions
}
/*!
- Tries to find a file or directory called \a fileName in the standard locations
- for \a type.
-
- The full path to the first file or directory (depending on \a options) found is returned.
- If no such file or directory can be found, an empty string is returned.
+ \include standardpath/functiondocs.qdocinc locate
*/
QString QStandardPaths::locate(StandardLocation type, const QString &fileName, LocateOptions options)
{
@@ -416,12 +404,7 @@ QString QStandardPaths::locate(StandardLocation type, const QString &fileName, L
}
/*!
- Tries to find all files or directories called \a fileName in the standard locations
- for \a type.
-
- The \a options flag allows to specify whether to look for files or directories.
-
- Returns the list of all the files that were found.
+ \include standardpath/functiondocs.qdocinc locateAll
*/
QStringList QStandardPaths::locateAll(StandardLocation type, const QString &fileName, LocateOptions options)
{
@@ -494,23 +477,7 @@ static inline QString
#endif // Q_OS_WIN
/*!
- Finds the executable named \a executableName in the paths specified by \a paths,
- or the system paths if \a paths is empty.
-
- On most operating systems the system path is determined by the PATH environment variable.
-
- The directories where to search for the executable can be set in the \a paths argument.
- To search in both your own paths and the system paths, call findExecutable twice, once with
- \a paths set and once with \a paths empty.
-
- Symlinks are not resolved, in order to preserve behavior for the case of executables
- whose behavior depends on the name they are invoked with.
-
- \note On Windows, the usual executable extensions (from the PATHEXT environment variable)
- are automatically appended, so that for instance findExecutable("foo") will find foo.exe
- or foo.bat if present.
-
- Returns the absolute file path to the executable, or an empty string if not found.
+ \include standardpath/functiondocs.qdocinc findExecutable
*/
QString QStandardPaths::findExecutable(const QString &executableName, const QStringList &paths)
{
@@ -568,10 +535,7 @@ QString QStandardPaths::findExecutable(const QString &executableName, const QStr
}
/*!
- \fn QString QStandardPaths::displayName(StandardLocation type)
-
- Returns a localized display name for the given location \a type or
- an empty QString if no relevant location can be found.
+ \include standardpath/functiondocs.qdocinc displayName
*/
#if !defined(Q_OS_MAC) && !defined(QT_BOOTSTRAPPED)
@@ -628,23 +592,7 @@ QString QStandardPaths::displayName(StandardLocation type)
/*!
\fn void QStandardPaths::setTestModeEnabled(bool testMode)
- If \a testMode is true, this enables a special "test mode" in
- QStandardPaths, which changes writable locations
- to point to test directories, in order to prevent auto tests from reading from
- or writing to the current user's configuration.
-
- This affects the locations into which test programs might write files:
- GenericDataLocation, DataLocation, ConfigLocation, GenericConfigLocation,
- AppConfigLocation, GenericCacheLocation, CacheLocation.
- Other locations are not affected.
-
- On Unix, \c XDG_DATA_HOME is set to \e ~/.qttest/share, \c XDG_CONFIG_HOME is
- set to \e ~/.qttest/config, and \c XDG_CACHE_HOME is set to \e ~/.qttest/cache.
-
- On \macos, data goes to \e ~/.qttest/Application Support, cache goes to
- \e ~/.qttest/Cache, and config goes to \e ~/.qttest/Preferences.
-
- On Windows, everything goes to a "qttest" directory under Application Data.
+ \include standardpath/functiondocs.qdocinc setTestModeEnabled
*/
static bool qsp_testMode = false;
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index 1e72241e68..37b8a60c37 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -108,7 +108,7 @@
# endif // QT_LARGEFILE_SUPPORT
#endif // Q_OS_BSD4
-#if QT_HAS_INCLUDE(<paths.h>)
+#if __has_include(<paths.h>)
# include <paths.h>
#endif
#ifndef _PATH_MOUNTED
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index acd31f4d84..55d13dad70 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -631,6 +631,12 @@ QString QTemporaryFilePrivate::defaultTemplateName()
case sensitive. If the template is not present in the filename,
QTemporaryFile appends the generated part to the filename given.
+ \note On Linux, QTemporaryFile will attempt to create unnamed temporary
+ files. If that succeeds, open() will return true but exists() will be
+ false. If you call fileName() or any function that calls it,
+ QTemporaryFile will give the file a name, so most applications will
+ not see a difference.
+
\sa QDir::tempPath(), QFile
*/
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index a7650390f9..0a5f9256eb 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -823,7 +823,7 @@ recodeFromUser(const QString &input, const ushort *actions, int from, int to)
QString output;
const QChar *begin = input.constData() + from;
const QChar *end = input.constData() + to;
- if (qt_urlRecode(output, begin, end, nullptr, actions))
+ if (qt_urlRecode(output, begin, end, {}, actions))
return output;
return input.mid(from, to - from);