diff options
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/io.pri | 1 | ||||
-rw-r--r-- | src/corelib/io/qabstractfileengine.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qfileinfo.cpp | 21 | ||||
-rw-r--r-- | src/corelib/io/qfileinfo.h | 1 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_win.cpp | 103 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemmetadata_p.h | 21 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine.cpp | 116 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_unix.cpp | 77 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_win.cpp | 74 | ||||
-rw-r--r-- | src/corelib/io/qprocess_unix.cpp | 6 | ||||
-rw-r--r-- | src/corelib/io/qprocess_win.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qresource.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qsettings.cpp | 15 | ||||
-rw-r--r-- | src/corelib/io/qsettings_p.h | 13 | ||||
-rw-r--r-- | src/corelib/io/qsettings_wasm.cpp | 259 | ||||
-rw-r--r-- | src/corelib/io/qurl.cpp | 2 |
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 ©Name) - - 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 ©Name) +{ + 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 ©Name) -{ - 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); |