1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QFSFILEENGINE_P_H
5#define QFSFILEENGINE_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qplatformdefs.h"
19#include "QtCore/private/qabstractfileengine_p.h"
20#include <QtCore/private/qfilesystementry_p.h>
21#include <QtCore/private/qfilesystemmetadata_p.h>
22#include <qhash.h>
23
24#include <optional>
25
26#ifdef Q_OS_UNIX
27#include <sys/types.h> // for mode_t
28#endif
29
30#ifndef QT_NO_FSFILEENGINE
31
32QT_BEGIN_NAMESPACE
33
34struct ProcessOpenModeResult
35{
36 bool ok;
37 QIODevice::OpenMode openMode;
38 QString error;
39};
40Q_CORE_EXPORT ProcessOpenModeResult processOpenModeFlags(QIODevice::OpenMode mode);
41
42class QFSFileEnginePrivate;
43
44class Q_CORE_EXPORT QFSFileEngine : public QAbstractFileEngine
45{
46 Q_DECLARE_PRIVATE(QFSFileEngine)
47public:
48 QFSFileEngine();
49 explicit QFSFileEngine(const QString &file);
50 ~QFSFileEngine();
51
52 bool open(QIODevice::OpenMode openMode, std::optional<QFile::Permissions> permissions) override;
53 bool open(QIODevice::OpenMode flags, FILE *fh);
54 bool close() override;
55 bool flush() override;
56 bool syncToDisk() override;
57 qint64 size() const override;
58 qint64 pos() const override;
59 bool seek(qint64) override;
60 bool isSequential() const override;
61 bool remove() override;
62 bool copy(const QString &newName) override;
63
64 bool rename(const QString &newName) override
65 { return rename_helper(newName, mode: Rename); }
66 bool renameOverwrite(const QString &newName) override
67 { return rename_helper(newName, mode: RenameOverwrite); }
68
69 bool link(const QString &newName) override;
70 bool mkdir(const QString &dirName, bool createParentDirectories,
71 std::optional<QFile::Permissions> permissions) const override;
72 bool rmdir(const QString &dirName, bool recurseParentDirectories) const override;
73 bool setSize(qint64 size) override;
74 bool caseSensitive() const override;
75 bool isRelativePath() const override;
76 FileFlags fileFlags(FileFlags type) const override;
77 bool setPermissions(uint perms) override;
78 QByteArray id() const override;
79 QString fileName(FileName file) const override;
80 uint ownerId(FileOwner) const override;
81 QString owner(FileOwner) const override;
82 bool setFileTime(const QDateTime &newDate, QFile::FileTime time) override;
83 QDateTime fileTime(QFile::FileTime time) const override;
84 void setFileName(const QString &file) override;
85 void setFileEntry(QFileSystemEntry &&entry);
86 int handle() const override;
87
88#ifndef QT_NO_FILESYSTEMITERATOR
89 IteratorUniquePtr beginEntryList(const QString &path, QDirListing::IteratorFlags filters,
90 const QStringList &filterNames) override;
91#endif
92
93 qint64 read(char *data, qint64 maxlen) override;
94 qint64 readLine(char *data, qint64 maxlen) override;
95 qint64 write(const char *data, qint64 len) override;
96 bool cloneTo(QAbstractFileEngine *target) override;
97
98 virtual bool isUnnamedFile() const
99 { return false; }
100
101 bool extension(Extension extension, const ExtensionOption *option = nullptr, ExtensionReturn *output = nullptr) override;
102 bool supportsExtension(Extension extension) const override;
103
104 //FS only!!
105 bool open(QIODevice::OpenMode flags, int fd);
106 bool open(QIODevice::OpenMode flags, int fd, QFile::FileHandleFlags handleFlags);
107 bool open(QIODevice::OpenMode flags, FILE *fh, QFile::FileHandleFlags handleFlags);
108 static bool setCurrentPath(const QString &path);
109 static QString currentPath(const QString &path = QString());
110 static QString homePath();
111 static QString rootPath();
112 static QString tempPath();
113 static QFileInfoList drives();
114
115protected:
116 QFSFileEngine(QFSFileEnginePrivate &dd);
117
118private:
119 enum RenameMode : int { Rename, RenameOverwrite };
120 bool rename_helper(const QString &newName, RenameMode mode);
121};
122
123class Q_AUTOTEST_EXPORT QFSFileEnginePrivate : public QAbstractFileEnginePrivate
124{
125 Q_DECLARE_PUBLIC(QFSFileEngine)
126
127public:
128#ifdef Q_OS_WIN
129 static QString longFileName(const QString &path);
130#endif
131
132 QFileSystemEntry fileEntry;
133 QIODevice::OpenMode openMode;
134
135 bool nativeOpen(QIODevice::OpenMode openMode, std::optional<QFile::Permissions> permissions);
136 bool openFh(QIODevice::OpenMode flags, FILE *fh);
137 bool openFd(QIODevice::OpenMode flags, int fd);
138 bool nativeClose();
139 bool closeFdFh();
140 bool nativeFlush();
141 bool nativeSyncToDisk();
142 bool flushFh();
143 qint64 nativeSize() const;
144#ifndef Q_OS_WIN
145 qint64 sizeFdFh() const;
146#endif
147 qint64 nativePos() const;
148 qint64 posFdFh() const;
149 bool nativeSeek(qint64);
150 bool seekFdFh(qint64);
151 qint64 nativeRead(char *data, qint64 maxlen);
152 qint64 readFdFh(char *data, qint64 maxlen);
153 qint64 nativeReadLine(char *data, qint64 maxlen);
154 qint64 readLineFdFh(char *data, qint64 maxlen);
155 qint64 nativeWrite(const char *data, qint64 len);
156 qint64 writeFdFh(const char *data, qint64 len);
157 int nativeHandle() const;
158 bool nativeIsSequential() const;
159#ifndef Q_OS_WIN
160 bool isSequentialFdFh() const;
161#endif
162#ifdef Q_OS_WIN
163 bool nativeRenameOverwrite(const QFileSystemEntry &newEntry);
164#endif
165
166 uchar *map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags);
167 bool unmap(uchar *ptr);
168 void unmapAll();
169
170 mutable QFileSystemMetaData metaData;
171
172 FILE *fh;
173
174#ifdef Q_OS_WIN
175 HANDLE fileHandle;
176 HANDLE mapHandle;
177 QHash<uchar *, DWORD /* offset % AllocationGranularity */> maps;
178
179 mutable int cachedFd;
180 mutable DWORD fileAttrib;
181#else
182 struct StartAndLength {
183 int start; // offset % PageSize
184 size_t length; // length + offset % PageSize
185 };
186 QHash<uchar *, StartAndLength> maps;
187#endif
188 int fd;
189
190 enum LastIOCommand
191 {
192 IOFlushCommand,
193 IOReadCommand,
194 IOWriteCommand
195 };
196 LastIOCommand lastIOCommand;
197 bool lastFlushFailed;
198 bool closeFileHandle;
199
200 mutable uint is_sequential : 2;
201 mutable uint tried_stat : 1;
202 mutable uint need_lstat : 1;
203 mutable uint is_link : 1;
204
205#if defined(Q_OS_WIN)
206 bool doStat(QFileSystemMetaData::MetaDataFlags flags) const;
207#else
208 bool doStat(QFileSystemMetaData::MetaDataFlags flags = QFileSystemMetaData::PosixStatFlags) const;
209#endif
210 bool isSymlink() const;
211
212#if defined(Q_OS_WIN32)
213 int sysOpen(const QString &, int flags);
214#endif
215
216 static bool openModeCanCreate(QIODevice::OpenMode openMode)
217 {
218 // WriteOnly can create, but only when ExistingOnly isn't specified.
219 // ReadOnly by itself never creates.
220 return (openMode & QFile::WriteOnly) && !(openMode & QFile::ExistingOnly);
221 }
222protected:
223 QFSFileEnginePrivate();
224
225 void init();
226
227 QAbstractFileEngine::FileFlags getPermissions(QAbstractFileEngine::FileFlags type) const;
228
229#ifdef Q_OS_UNIX
230 bool nativeOpenImpl(QIODevice::OpenMode openMode, mode_t mode);
231#endif
232};
233
234QT_END_NAMESPACE
235
236#endif // QT_NO_FSFILEENGINE
237
238#endif // QFSFILEENGINE_P_H
239

source code of qtbase/src/corelib/io/qfsfileengine_p.h