QAbstractFileEngine: Add permission argument to open()
The new argument allows atomic creation of files with non-default permissions. Task-number: QTBUG-79750 Change-Id: I4c49455b41f924ba87148302c8d0f77f5de0832b Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
56bd1b76d2
commit
56e13acf4e
@ -383,10 +383,16 @@ QAbstractFileEngine::~QAbstractFileEngine()
|
|||||||
|
|
||||||
The \a mode is an OR combination of QIODevice::OpenMode and
|
The \a mode is an OR combination of QIODevice::OpenMode and
|
||||||
QIODevice::HandlingMode values.
|
QIODevice::HandlingMode values.
|
||||||
|
|
||||||
|
If the file is created as a result of this call, its permissions are
|
||||||
|
set according to \a permissision. Null value means an implementation-
|
||||||
|
specific default.
|
||||||
*/
|
*/
|
||||||
bool QAbstractFileEngine::open(QIODevice::OpenMode openMode)
|
bool QAbstractFileEngine::open(QIODevice::OpenMode openMode,
|
||||||
|
std::optional<QFile::Permissions> permissions)
|
||||||
{
|
{
|
||||||
Q_UNUSED(openMode);
|
Q_UNUSED(openMode);
|
||||||
|
Q_UNUSED(permissions);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,8 @@ public:
|
|||||||
|
|
||||||
virtual ~QAbstractFileEngine();
|
virtual ~QAbstractFileEngine();
|
||||||
|
|
||||||
virtual bool open(QIODevice::OpenMode openMode);
|
virtual bool open(QIODevice::OpenMode openMode,
|
||||||
|
std::optional<QFile::Permissions> permissions = std::nullopt);
|
||||||
virtual bool close();
|
virtual bool close();
|
||||||
virtual bool flush();
|
virtual bool flush();
|
||||||
virtual bool syncToDisk();
|
virtual bool syncToDisk();
|
||||||
|
@ -226,7 +226,8 @@ void QFSFileEngine::setFileName(const QString &file)
|
|||||||
/*!
|
/*!
|
||||||
\reimp
|
\reimp
|
||||||
*/
|
*/
|
||||||
bool QFSFileEngine::open(QIODevice::OpenMode openMode)
|
bool QFSFileEngine::open(QIODevice::OpenMode openMode,
|
||||||
|
std::optional<QFile::Permissions> permissions)
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(openMode & QIODevice::Unbuffered, "QFSFileEngine::open",
|
Q_ASSERT_X(openMode & QIODevice::Unbuffered, "QFSFileEngine::open",
|
||||||
"QFSFileEngine no longer supports buffered mode; upper layer must buffer");
|
"QFSFileEngine no longer supports buffered mode; upper layer must buffer");
|
||||||
@ -250,7 +251,7 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode)
|
|||||||
d->fh = nullptr;
|
d->fh = nullptr;
|
||||||
d->fd = -1;
|
d->fd = -1;
|
||||||
|
|
||||||
return d->nativeOpen(d->openMode);
|
return d->nativeOpen(d->openMode, permissions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -59,6 +59,10 @@
|
|||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
#include <sys/types.h> // for mode_t
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef QT_NO_FSFILEENGINE
|
#ifndef QT_NO_FSFILEENGINE
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -81,7 +85,7 @@ public:
|
|||||||
explicit QFSFileEngine(const QString &file);
|
explicit QFSFileEngine(const QString &file);
|
||||||
~QFSFileEngine();
|
~QFSFileEngine();
|
||||||
|
|
||||||
bool open(QIODevice::OpenMode openMode) override;
|
bool open(QIODevice::OpenMode openMode, std::optional<QFile::Permissions> permissions) override;
|
||||||
bool open(QIODevice::OpenMode flags, FILE *fh);
|
bool open(QIODevice::OpenMode flags, FILE *fh);
|
||||||
bool close() override;
|
bool close() override;
|
||||||
bool flush() override;
|
bool flush() override;
|
||||||
@ -156,7 +160,7 @@ public:
|
|||||||
QFileSystemEntry fileEntry;
|
QFileSystemEntry fileEntry;
|
||||||
QIODevice::OpenMode openMode;
|
QIODevice::OpenMode openMode;
|
||||||
|
|
||||||
bool nativeOpen(QIODevice::OpenMode openMode);
|
bool nativeOpen(QIODevice::OpenMode openMode, std::optional<QFile::Permissions> permissions);
|
||||||
bool openFh(QIODevice::OpenMode flags, FILE *fh);
|
bool openFh(QIODevice::OpenMode flags, FILE *fh);
|
||||||
bool openFd(QIODevice::OpenMode flags, int fd);
|
bool openFd(QIODevice::OpenMode flags, int fd);
|
||||||
bool nativeClose();
|
bool nativeClose();
|
||||||
@ -246,6 +250,10 @@ protected:
|
|||||||
void init();
|
void init();
|
||||||
|
|
||||||
QAbstractFileEngine::FileFlags getPermissions(QAbstractFileEngine::FileFlags type) const;
|
QAbstractFileEngine::FileFlags getPermissions(QAbstractFileEngine::FileFlags type) const;
|
||||||
|
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
bool nativeOpenImpl(QIODevice::OpenMode openMode, mode_t mode);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#include "qplatformdefs.h"
|
#include "qplatformdefs.h"
|
||||||
#include "private/qabstractfileengine_p.h"
|
#include "private/qabstractfileengine_p.h"
|
||||||
|
#include "private/qfiledevice_p.h"
|
||||||
#include "private/qfsfileengine_p.h"
|
#include "private/qfsfileengine_p.h"
|
||||||
#include "private/qcore_unix_p.h"
|
#include "private/qcore_unix_p.h"
|
||||||
#include "qfilesystementry_p.h"
|
#include "qfilesystementry_p.h"
|
||||||
@ -107,7 +108,16 @@ static inline QString msgOpenDirectory()
|
|||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
*/
|
*/
|
||||||
bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
|
bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode,
|
||||||
|
std::optional<QFile::Permissions> permissions)
|
||||||
|
{
|
||||||
|
return nativeOpenImpl(openMode, permissions ? QtPrivate::toMode_t(*permissions) : 0666);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
*/
|
||||||
|
bool QFSFileEnginePrivate::nativeOpenImpl(QIODevice::OpenMode openMode, mode_t mode)
|
||||||
{
|
{
|
||||||
Q_Q(QFSFileEngine);
|
Q_Q(QFSFileEngine);
|
||||||
|
|
||||||
@ -118,7 +128,7 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
|
|||||||
|
|
||||||
// Try to open the file in unbuffered mode.
|
// Try to open the file in unbuffered mode.
|
||||||
do {
|
do {
|
||||||
fd = QT_OPEN(fileEntry.nativeFilePath().constData(), flags, 0666);
|
fd = QT_OPEN(fileEntry.nativeFilePath().constData(), flags, mode);
|
||||||
} while (fd == -1 && errno == EINTR);
|
} while (fd == -1 && errno == EINTR);
|
||||||
|
|
||||||
// On failure, return and report the error.
|
// On failure, return and report the error.
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#include "qplatformdefs.h"
|
#include "qplatformdefs.h"
|
||||||
#include "private/qabstractfileengine_p.h"
|
#include "private/qabstractfileengine_p.h"
|
||||||
|
#include "private/qfiledevice_p.h"
|
||||||
#include "private/qfsfileengine_p.h"
|
#include "private/qfsfileengine_p.h"
|
||||||
#include "qfilesystemengine_p.h"
|
#include "qfilesystemengine_p.h"
|
||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
@ -95,7 +96,8 @@ QString QFSFileEnginePrivate::longFileName(const QString &path)
|
|||||||
/*
|
/*
|
||||||
\internal
|
\internal
|
||||||
*/
|
*/
|
||||||
bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
|
bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode,
|
||||||
|
std::optional<QFile::Permissions> permissions)
|
||||||
{
|
{
|
||||||
Q_Q(QFSFileEngine);
|
Q_Q(QFSFileEngine);
|
||||||
|
|
||||||
@ -115,11 +117,14 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
|
|||||||
? OPEN_ALWAYS
|
? OPEN_ALWAYS
|
||||||
: OPEN_EXISTING;
|
: OPEN_EXISTING;
|
||||||
// Create the file handle.
|
// Create the file handle.
|
||||||
SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
|
QNativeFilePermissions nativePermissions(permissions, false);
|
||||||
|
if (!nativePermissions.isOk())
|
||||||
|
return false;
|
||||||
|
|
||||||
fileHandle = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(),
|
fileHandle = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(),
|
||||||
accessRights,
|
accessRights,
|
||||||
shareMode,
|
shareMode,
|
||||||
&securityAtts,
|
nativePermissions.securityAttributes(),
|
||||||
creationDisp,
|
creationDisp,
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
NULL);
|
NULL);
|
||||||
|
@ -1409,8 +1409,11 @@ void QResourceFileEngine::setFileName(const QString &file)
|
|||||||
d->resource.setFileName(file);
|
d->resource.setFileName(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QResourceFileEngine::open(QIODevice::OpenMode flags)
|
bool QResourceFileEngine::open(QIODevice::OpenMode flags,
|
||||||
|
std::optional<QFile::Permissions> permissions)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(permissions);
|
||||||
|
|
||||||
Q_D(QResourceFileEngine);
|
Q_D(QResourceFileEngine);
|
||||||
if (d->resource.fileName().isEmpty()) {
|
if (d->resource.fileName().isEmpty()) {
|
||||||
qWarning("QResourceFileEngine::open: Missing file name");
|
qWarning("QResourceFileEngine::open: Missing file name");
|
||||||
|
@ -66,7 +66,7 @@ public:
|
|||||||
|
|
||||||
void setFileName(const QString &file) override;
|
void setFileName(const QString &file) override;
|
||||||
|
|
||||||
bool open(QIODevice::OpenMode flags) override;
|
bool open(QIODevice::OpenMode flags, std::optional<QFile::Permissions> permissions) override;
|
||||||
bool close() override;
|
bool close() override;
|
||||||
bool flush() override;
|
bool flush() override;
|
||||||
qint64 size() const override;
|
qint64 size() const override;
|
||||||
|
@ -340,7 +340,8 @@ void QTemporaryFileEngine::setFileName(const QString &file)
|
|||||||
QFSFileEngine::setFileName(file);
|
QFSFileEngine::setFileName(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
|
bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode,
|
||||||
|
std::optional<QFile::Permissions> permissions)
|
||||||
{
|
{
|
||||||
Q_D(QFSFileEngine);
|
Q_D(QFSFileEngine);
|
||||||
Q_ASSERT(!isReallyOpen());
|
Q_ASSERT(!isReallyOpen());
|
||||||
@ -348,7 +349,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
|
|||||||
openMode |= QIODevice::ReadWrite;
|
openMode |= QIODevice::ReadWrite;
|
||||||
|
|
||||||
if (!filePathIsTemplate)
|
if (!filePathIsTemplate)
|
||||||
return QFSFileEngine::open(openMode);
|
return QFSFileEngine::open(openMode, permissions);
|
||||||
|
|
||||||
QTemporaryFileName tfn(templateName);
|
QTemporaryFileName tfn(templateName);
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ public:
|
|||||||
bool isReallyOpen() const;
|
bool isReallyOpen() const;
|
||||||
void setFileName(const QString &file) override;
|
void setFileName(const QString &file) override;
|
||||||
|
|
||||||
bool open(QIODevice::OpenMode flags) override;
|
bool open(QIODevice::OpenMode flags, std::optional<QFile::Permissions> permissions) override;
|
||||||
bool remove() override;
|
bool remove() override;
|
||||||
bool rename(const QString &newName) override;
|
bool rename(const QString &newName) override;
|
||||||
bool renameOverwrite(const QString &newName) override;
|
bool renameOverwrite(const QString &newName) override;
|
||||||
|
@ -54,8 +54,10 @@ AndroidContentFileEngine::AndroidContentFileEngine(const QString &f)
|
|||||||
setFileName(f);
|
setFileName(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
|
bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode,
|
||||||
|
std::optional<QFile::Permissions> permissions)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(permissions);
|
||||||
QString openModeStr;
|
QString openModeStr;
|
||||||
if (openMode & QFileDevice::ReadOnly) {
|
if (openMode & QFileDevice::ReadOnly) {
|
||||||
openModeStr += QLatin1Char('r');
|
openModeStr += QLatin1Char('r');
|
||||||
|
@ -46,7 +46,7 @@ class AndroidContentFileEngine : public QFSFileEngine
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AndroidContentFileEngine(const QString &fileName);
|
AndroidContentFileEngine(const QString &fileName);
|
||||||
bool open(QIODevice::OpenMode openMode) override;
|
bool open(QIODevice::OpenMode openMode, std::optional<QFile::Permissions> permissions) override;
|
||||||
qint64 size() const override;
|
qint64 size() const override;
|
||||||
FileFlags fileFlags(FileFlags type = FileInfoAll) const override;
|
FileFlags fileFlags(FileFlags type = FileInfoAll) const override;
|
||||||
QString fileName(FileName file = DefaultName) const override;
|
QString fileName(FileName file = DefaultName) const override;
|
||||||
|
@ -261,8 +261,10 @@ public:
|
|||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool open(QIODevice::OpenMode openMode) override
|
bool open(QIODevice::OpenMode openMode, std::optional<QFile::Permissions> permissions) override
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(permissions);
|
||||||
|
|
||||||
if (m_isFolder || (openMode & QIODevice::WriteOnly))
|
if (m_isFolder || (openMode & QIODevice::WriteOnly))
|
||||||
return false;
|
return false;
|
||||||
close();
|
close();
|
||||||
@ -358,7 +360,7 @@ public:
|
|||||||
m_fileName = cleanedAssetPath(file);
|
m_fileName = cleanedAssetPath(file);
|
||||||
switch (FolderIterator::fileType(m_fileName)) {
|
switch (FolderIterator::fileType(m_fileName)) {
|
||||||
case AssetItem::Type::File:
|
case AssetItem::Type::File:
|
||||||
open(QIODevice::ReadOnly);
|
open(QIODevice::ReadOnly, std::nullopt);
|
||||||
break;
|
break;
|
||||||
case AssetItem::Type::Folder:
|
case AssetItem::Type::Folder:
|
||||||
m_isFolder = true;
|
m_isFolder = true;
|
||||||
|
@ -54,7 +54,7 @@ public:
|
|||||||
QIOSFileEngineAssetsLibrary(const QString &fileName);
|
QIOSFileEngineAssetsLibrary(const QString &fileName);
|
||||||
~QIOSFileEngineAssetsLibrary();
|
~QIOSFileEngineAssetsLibrary();
|
||||||
|
|
||||||
bool open(QIODevice::OpenMode openMode) override;
|
bool open(QIODevice::OpenMode openMode, std::optional<QFile::Permissions> permissions) override;
|
||||||
bool close() override;
|
bool close() override;
|
||||||
FileFlags fileFlags(FileFlags type) const override;
|
FileFlags fileFlags(FileFlags type) const override;
|
||||||
qint64 size() const override;
|
qint64 size() const override;
|
||||||
|
@ -353,8 +353,11 @@ ALAsset *QIOSFileEngineAssetsLibrary::loadAsset() const
|
|||||||
return m_data->m_asset;
|
return m_data->m_asset;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QIOSFileEngineAssetsLibrary::open(QIODevice::OpenMode openMode)
|
bool QIOSFileEngineAssetsLibrary::open(QIODevice::OpenMode openMode,
|
||||||
|
std::optional<QFile::Permissions> permissions)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(permissions);
|
||||||
|
|
||||||
if (openMode & (QIODevice::WriteOnly | QIODevice::Text))
|
if (openMode & (QIODevice::WriteOnly | QIODevice::Text))
|
||||||
return false;
|
return false;
|
||||||
return loadAsset();
|
return loadAsset();
|
||||||
|
@ -76,8 +76,10 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool open(QIODevice::OpenMode openMode) override
|
bool open(QIODevice::OpenMode openMode, std::optional<QFile::Permissions> permissions) override
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(permissions);
|
||||||
|
|
||||||
if (openForRead_ || openForWrite_) {
|
if (openForRead_ || openForWrite_) {
|
||||||
qWarning("%s: file is already open for %s",
|
qWarning("%s: file is already open for %s",
|
||||||
Q_FUNC_INFO,
|
Q_FUNC_INFO,
|
||||||
|
@ -263,7 +263,7 @@ void tst_qfile::readBigFile()
|
|||||||
#ifdef QT_BUILD_INTERNAL
|
#ifdef QT_BUILD_INTERNAL
|
||||||
case QFSFileEngineBenchmark: {
|
case QFSFileEngineBenchmark: {
|
||||||
QFSFileEngine fse(tempDir.filename);
|
QFSFileEngine fse(tempDir.filename);
|
||||||
fse.open(QIODevice::ReadOnly|textMode|bufferedMode);
|
fse.open(QIODevice::ReadOnly | textMode | bufferedMode, std::nullopt);
|
||||||
QBENCHMARK {
|
QBENCHMARK {
|
||||||
//qWarning() << fse.supportsExtension(QAbstractFileEngine::AtEndExtension);
|
//qWarning() << fse.supportsExtension(QAbstractFileEngine::AtEndExtension);
|
||||||
while (fse.read(buffer, blockSize)) {}
|
while (fse.read(buffer, blockSize)) {}
|
||||||
@ -349,7 +349,7 @@ void tst_qfile::seek()
|
|||||||
#ifdef QT_BUILD_INTERNAL
|
#ifdef QT_BUILD_INTERNAL
|
||||||
case QFSFileEngineBenchmark: {
|
case QFSFileEngineBenchmark: {
|
||||||
QFSFileEngine fse(tempDir.filename);
|
QFSFileEngine fse(tempDir.filename);
|
||||||
fse.open(QIODevice::ReadOnly | QIODevice::Unbuffered);
|
fse.open(QIODevice::ReadOnly | QIODevice::Unbuffered, std::nullopt);
|
||||||
QBENCHMARK {
|
QBENCHMARK {
|
||||||
i=(i+1)%sp_size;
|
i=(i+1)%sp_size;
|
||||||
fse.seek(seekpos[i]);
|
fse.seek(seekpos[i]);
|
||||||
@ -426,7 +426,7 @@ void tst_qfile::open()
|
|||||||
case QFSFileEngineBenchmark: {
|
case QFSFileEngineBenchmark: {
|
||||||
QBENCHMARK {
|
QBENCHMARK {
|
||||||
QFSFileEngine fse(tempDir.filename);
|
QFSFileEngine fse(tempDir.filename);
|
||||||
fse.open(QIODevice::ReadOnly | QIODevice::Unbuffered);
|
fse.open(QIODevice::ReadOnly | QIODevice::Unbuffered, std::nullopt);
|
||||||
fse.close();
|
fse.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -550,7 +550,7 @@ void tst_qfile::readSmallFiles()
|
|||||||
QList<QFSFileEngine*> fileList;
|
QList<QFSFileEngine*> fileList;
|
||||||
for (const QString &file : files) {
|
for (const QString &file : files) {
|
||||||
QFSFileEngine *fse = new QFSFileEngine(tempDir.filePath(file));
|
QFSFileEngine *fse = new QFSFileEngine(tempDir.filePath(file));
|
||||||
fse->open(QIODevice::ReadOnly|textMode|bufferedMode);
|
fse->open(QIODevice::ReadOnly | textMode | bufferedMode, std::nullopt);
|
||||||
fileList.append(fse);
|
fileList.append(fse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user