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/qfileinfo.cpp21
-rw-r--r--src/corelib/io/qfileinfo.h1
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp103
-rw-r--r--src/corelib/io/qfilesystemmetadata_p.h21
-rw-r--r--src/corelib/io/qfsfileengine.cpp116
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp77
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp74
-rw-r--r--src/corelib/io/qprocess_unix.cpp6
-rw-r--r--src/corelib/io/qprocess_win.cpp2
-rw-r--r--src/corelib/io/qresource.cpp2
-rw-r--r--src/corelib/io/qsettings.cpp15
-rw-r--r--src/corelib/io/qsettings_p.h13
-rw-r--r--src/corelib/io/qsettings_wasm.cpp259
-rw-r--r--src/corelib/io/qurl.cpp2
16 files changed, 457 insertions, 258 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/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_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index ae29190848..0579872f8d 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -1123,67 +1123,62 @@ static bool isDirPath(const QString &dirPath, bool *existed)
return fileAttrib & FILE_ATTRIBUTE_DIRECTORY;
}
+// NOTE: if \a shouldMkdirFirst is false, we assume the caller did try to mkdir
+// before calling this function.
+static bool createDirectoryWithParents(const QString &nativeName, bool shouldMkdirFirst = true)
+{
+ const auto isUNCRoot = [](const QString &nativeName) {
+ return nativeName.startsWith(QLatin1String("\\\\")) && nativeName.count(QDir::separator()) <= 3;
+ };
+ const auto isDriveName = [](const QString &nativeName) {
+ return nativeName.size() == 2 && nativeName.at(1) == QLatin1Char(':');
+ };
+ const auto isDir = [](const QString &nativeName) {
+ bool exists = false;
+ return isDirPath(nativeName, &exists) && exists;
+ };
+ // Do not try to mkdir a UNC root path or a drive letter.
+ if (isUNCRoot(nativeName) || isDriveName(nativeName))
+ return false;
+
+ if (shouldMkdirFirst) {
+ if (mkDir(nativeName))
+ return true;
+ }
+
+ const int backSlash = nativeName.lastIndexOf(QDir::separator());
+ if (backSlash < 1)
+ return false;
+
+ const QString parentNativeName = nativeName.left(backSlash);
+ if (!createDirectoryWithParents(parentNativeName))
+ return false;
+
+ // try again
+ if (mkDir(nativeName))
+ return true;
+ return isDir(nativeName);
+}
+
//static
bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool createParents)
{
QString dirName = entry.filePath();
Q_CHECK_FILE_NAME(dirName, false);
- if (createParents) {
- dirName = QDir::toNativeSeparators(QDir::cleanPath(dirName));
- // We spefically search for / so \ would break it..
- int oldslash = -1;
- if (dirName.startsWith(QLatin1String("\\\\"))) {
- // Don't try to create the root path of a UNC path;
- // CreateDirectory() will just return ERROR_INVALID_NAME.
- for (int i = 0; i < dirName.size(); ++i) {
- if (dirName.at(i) != QDir::separator()) {
- oldslash = i;
- break;
- }
- }
- if (oldslash != -1)
- oldslash = dirName.indexOf(QDir::separator(), oldslash);
- } else if (dirName.size() > 2
- && dirName.at(1) == QLatin1Char(':')) {
- // Don't try to call mkdir with just a drive letter
- oldslash = 2;
- }
- for (int slash=0; slash != -1; oldslash = slash) {
- slash = dirName.indexOf(QDir::separator(), oldslash+1);
- if (slash == -1) {
- if (oldslash == dirName.length())
- break;
- slash = dirName.length();
- }
- if (slash) {
- DWORD lastError;
- QString chunk = dirName.left(slash);
- if (!mkDir(chunk, &lastError)) {
- if (lastError == ERROR_ALREADY_EXISTS || lastError == ERROR_ACCESS_DENIED) {
- bool existed = false;
- if (isDirPath(chunk, &existed) && existed)
- continue;
-#ifdef Q_OS_WINRT
- static QThreadStorage<QString> dataLocation;
- if (!dataLocation.hasLocalData())
- dataLocation.setLocalData(QDir::toNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation)));
- static QThreadStorage<QString> tempLocation;
- if (!tempLocation.hasLocalData())
- tempLocation.setLocalData(QDir::toNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::TempLocation)));
- // We try to create something outside the sandbox, which is forbidden
- // However we could still try to pass into the sandbox
- if (dataLocation.localData().startsWith(chunk) || tempLocation.localData().startsWith(chunk))
- continue;
-#endif
- }
- return false;
- }
- }
- }
+ dirName = QDir::toNativeSeparators(QDir::cleanPath(dirName));
+
+ // try to mkdir this directory
+ DWORD lastError;
+ if (mkDir(dirName, &lastError))
return true;
- }
- return mkDir(entry.filePath());
+ // mkpath should return true, if the directory already exists, mkdir false.
+ if (!createParents)
+ return false;
+ if (lastError == ERROR_ALREADY_EXISTS)
+ return isDirPath(dirName, nullptr);
+
+ return createDirectoryWithParents(dirName, false);
}
//static
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/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index 0d73839f8d..3042eac2f0 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -911,14 +911,7 @@ bool QFSFileEngine::supportsExtension(Extension extension) const
}
/*! \fn bool QFSFileEngine::caseSensitive() const
- Returns \c true for Windows, false for Unix.
-*/
-
-/*! \fn bool QFSFileEngine::copy(const QString &copyName)
-
- For Windows or Apple platforms, copy the file to file \a copyName.
-
- Not implemented for other Unix platforms.
+ Returns \c false for Windows, true for Unix.
*/
/*! \fn QString QFSFileEngine::currentPath(const QString &fileName)
@@ -950,11 +943,34 @@ bool QFSFileEngine::supportsExtension(Extension extension) const
\reimp
*/
-/*! \fn QString QFSFileEngine::homePath()
+/*!
Returns the home path of the current user.
\sa rootPath()
*/
+QString QFSFileEngine::homePath()
+{
+ return QFileSystemEngine::homePath();
+}
+
+/*!
+ Returns the root path.
+
+ \sa homePath()
+*/
+QString QFSFileEngine::rootPath()
+{
+ return QFileSystemEngine::rootPath();
+}
+
+/*!
+ Returns the temporary path (i.e., a path in which it is safe
+ to store temporary files).
+*/
+QString QFSFileEngine::tempPath()
+{
+ return QFileSystemEngine::tempPath();
+}
/*! \fn bool QFSFileEngine::isRelativePath() const
\reimp
@@ -968,9 +984,6 @@ bool QFSFileEngine::supportsExtension(Extension extension) const
true if successful; otherwise returns \c false.
*/
-/*! \fn bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) const
- \reimp
-*/
/*! \fn uint QFSFileEngine::ownerId(QAbstractFileEngine::FileOwner own) const
In Unix, if stat() is successful, the \c uid is returned if
@@ -984,35 +997,87 @@ bool QFSFileEngine::supportsExtension(Extension extension) const
\reimp
*/
-/*! \fn bool QFSFileEngine::remove()
- \reimp
+/*!
+ For Windows or Apple platforms, copy the file to file \a copyName.
+
+ Not implemented for other Unix platforms.
*/
+bool QFSFileEngine::copy(const QString &copyName)
+{
+ Q_D(QFSFileEngine);
+ QSystemError error;
+ bool ret = QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(copyName), error);
+ if (!ret)
+ setError(QFile::CopyError, error.toString());
+ return ret;
+}
-/*! \fn bool QFSFileEngine::rename(const QString &newName)
+/*!
\reimp
*/
+bool QFSFileEngine::remove()
+{
+ Q_D(QFSFileEngine);
+ QSystemError error;
+ bool ret = QFileSystemEngine::removeFile(d->fileEntry, error);
+ d->metaData.clear();
+ if (!ret)
+ setError(QFile::RemoveError, error.toString());
+ return ret;
+}
-
-/*! \fn bool QFSFileEngine::renameOverwrite(const QString &newName)
+/*!
\reimp
*/
-
-/*! \fn bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const
+bool QFSFileEngine::rename(const QString &newName)
+{
+ Q_D(QFSFileEngine);
+ QSystemError error;
+ bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName), error);
+ if (!ret)
+ setError(QFile::RenameError, error.toString());
+ return ret;
+}
+/*!
\reimp
*/
+bool QFSFileEngine::renameOverwrite(const QString &newName)
+{
+ Q_D(QFSFileEngine);
+ QSystemError error;
+ bool ret = QFileSystemEngine::renameOverwriteFile(d->fileEntry, QFileSystemEntry(newName), error);
+ if (!ret)
+ setError(QFile::RenameError, error.toString());
+ return ret;
+}
-/*! \fn QString QFSFileEngine::rootPath()
- Returns the root path.
+/*!
+ \reimp
+*/
+bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) const
+{
+ return QFileSystemEngine::createDirectory(QFileSystemEntry(name), createParentDirectories);
+}
- \sa homePath()
+/*!
+ \reimp
*/
+bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const
+{
+ return QFileSystemEngine::removeDirectory(QFileSystemEntry(name), recurseParentDirectories);
+}
-/*! \fn bool QFSFileEngine::setCurrentPath(const QString &path)
+
+/*!
Sets the current path (e.g., for QDir), to \a path. Returns \c true if the
new path exists; otherwise this function does nothing, and returns \c false.
\sa currentPath()
*/
+bool QFSFileEngine::setCurrentPath(const QString &path)
+{
+ return QFileSystemEngine::setCurrentPath(QFileSystemEntry(path));
+}
/*! \fn bool QFSFileEngine::setPermissions(uint perms)
\reimp
@@ -1022,11 +1087,6 @@ bool QFSFileEngine::supportsExtension(Extension extension) const
\reimp
*/
-/*! \fn QString QFSFileEngine::tempPath()
- Returns the temporary path (i.e., a path in which it is safe
- to store temporary files).
-*/
-
/*! \fn QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions(QAbstractFileEngine::FileFlags type) const
\internal
*/
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index d4983c72af..4610e9306c 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -304,54 +304,6 @@ bool QFSFileEnginePrivate::nativeIsSequential() const
return isSequentialFdFh();
}
-bool QFSFileEngine::remove()
-{
- Q_D(QFSFileEngine);
- QSystemError error;
- bool ret = QFileSystemEngine::removeFile(d->fileEntry, error);
- d->metaData.clear();
- if (!ret) {
- setError(QFile::RemoveError, error.toString());
- }
- return ret;
-}
-
-bool QFSFileEngine::copy(const QString &newName)
-{
- Q_D(QFSFileEngine);
- QSystemError error;
- bool ret = QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(newName), error);
- if (!ret) {
- setError(QFile::CopyError, error.toString());
- }
- return ret;
-}
-
-bool QFSFileEngine::renameOverwrite(const QString &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)
-{
- Q_D(QFSFileEngine);
- QSystemError error;
- bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName), error);
-
- if (!ret) {
- setError(QFile::RenameError, error.toString());
- }
-
- return ret;
-}
-
bool QFSFileEngine::link(const QString &newName)
{
Q_D(QFSFileEngine);
@@ -368,45 +320,16 @@ qint64 QFSFileEnginePrivate::nativeSize() const
return sizeFdFh();
}
-bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) const
-{
- return QFileSystemEngine::createDirectory(QFileSystemEntry(name), createParentDirectories);
-}
-
-bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const
-{
- return QFileSystemEngine::removeDirectory(QFileSystemEntry(name), recurseParentDirectories);
-}
-
bool QFSFileEngine::caseSensitive() const
{
return true;
}
-bool QFSFileEngine::setCurrentPath(const QString &path)
-{
- return QFileSystemEngine::setCurrentPath(QFileSystemEntry(path));
-}
-
QString QFSFileEngine::currentPath(const QString &)
{
return QFileSystemEngine::currentPath().filePath();
}
-QString QFSFileEngine::homePath()
-{
- return QFileSystemEngine::homePath();
-}
-
-QString QFSFileEngine::rootPath()
-{
- return QFileSystemEngine::rootPath();
-}
-
-QString QFSFileEngine::tempPath()
-{
- return QFileSystemEngine::tempPath();
-}
QFileInfoList QFSFileEngine::drives()
{
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index 19cc3e6402..dd4882a2bc 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -443,66 +443,11 @@ bool QFSFileEnginePrivate::nativeIsSequential() const
#endif
}
-bool QFSFileEngine::remove()
-{
- Q_D(QFSFileEngine);
- QSystemError error;
- bool ret = QFileSystemEngine::removeFile(d->fileEntry, error);
- if (!ret)
- setError(QFile::RemoveError, error.toString());
- return ret;
-}
-
-bool QFSFileEngine::copy(const QString &copyName)
-{
- Q_D(QFSFileEngine);
- QSystemError error;
- bool ret = QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(copyName), error);
- if (!ret)
- setError(QFile::CopyError, error.toString());
- return ret;
-}
-
-bool QFSFileEngine::rename(const QString &newName)
-{
- Q_D(QFSFileEngine);
- QSystemError error;
- bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName), error);
- if (!ret)
- setError(QFile::RenameError, error.toString());
- return ret;
-}
-
-bool QFSFileEngine::renameOverwrite(const QString &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::mkdir(const QString &name, bool createParentDirectories) const
-{
- return QFileSystemEngine::createDirectory(QFileSystemEntry(name), createParentDirectories);
-}
-
-bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const
-{
- return QFileSystemEngine::removeDirectory(QFileSystemEntry(name), recurseParentDirectories);
-}
-
bool QFSFileEngine::caseSensitive() const
{
return false;
}
-bool QFSFileEngine::setCurrentPath(const QString &path)
-{
- return QFileSystemEngine::setCurrentPath(QFileSystemEntry(path));
-}
-
QString QFSFileEngine::currentPath(const QString &fileName)
{
#if !defined(Q_OS_WINRT)
@@ -530,21 +475,6 @@ QString QFSFileEngine::currentPath(const QString &fileName)
#endif // Q_OS_WINRT
}
-QString QFSFileEngine::homePath()
-{
- return QFileSystemEngine::homePath();
-}
-
-QString QFSFileEngine::rootPath()
-{
- return QFileSystemEngine::rootPath();
-}
-
-QString QFSFileEngine::tempPath()
-{
- return QFileSystemEngine::tempPath();
-}
-
#if !defined(Q_OS_WINRT)
// cf QStorageInfo::isReady
static inline bool isDriveReady(const wchar_t *path)
@@ -661,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/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 0c80daa024..9edb4a6d11 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);
@@ -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)),
@@ -517,7 +517,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()));
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index 3ba86063e3..05af5a5aee 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -590,7 +590,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 22c22ce711..0a145b2be4 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -1492,7 +1492,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;
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index fc7122d904..dcc9340473 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>
@@ -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)
{
@@ -1185,7 +1181,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,
@@ -1548,13 +1546,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);
}
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/qurl.cpp b/src/corelib/io/qurl.cpp
index 878e007fb0..659552b72f 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);