Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qfsfileengine.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qfsfileengine_p.h"
8#include "qdatetime.h"
9#include "qdiriterator.h"
10#include "qset.h"
11#include <QtCore/qdebug.h>
12
13#ifndef QT_NO_FSFILEENGINE
14
15#include <errno.h>
16#if defined(Q_OS_UNIX)
17#include "private/qcore_unix_p.h"
18#endif
19#include <stdio.h>
20#include <stdlib.h>
21#if defined(Q_OS_DARWIN)
22# include <private/qcore_mac_p.h>
23#endif
24
26
27using namespace Qt::StringLiterals;
28
29#ifdef Q_OS_WIN
30# ifndef S_ISREG
31# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
32# endif
33# ifndef S_ISCHR
34# define S_ISCHR(x) (((x) & S_IFMT) == S_IFCHR)
35# endif
36# ifndef S_ISFIFO
37# define S_ISFIFO(x) false
38# endif
39# ifndef S_ISSOCK
40# define S_ISSOCK(x) false
41# endif
42# ifndef INVALID_FILE_ATTRIBUTES
43# define INVALID_FILE_ATTRIBUTES (DWORD (-1))
44# endif
45#endif
46
47#ifdef Q_OS_WIN
48// on Windows, read() and write() use int and unsigned int
49typedef int SignedIOType;
50typedef unsigned int UnsignedIOType;
51#else
52typedef ssize_t SignedIOType;
53typedef size_t UnsignedIOType;
54static_assert(sizeof(SignedIOType) == sizeof(UnsignedIOType),
55 "Unsupported: read/write return a type with different size as the len parameter");
56#endif
57
79//**************** QFSFileEnginePrivate
81{
82 init();
83}
84
89{
90 is_sequential = 0;
91 tried_stat = 0;
92 need_lstat = 1;
93 is_link = 0;
95 fd = -1;
96 fh = nullptr;
98 lastFlushFailed = false;
99 closeFileHandle = false;
100#ifdef Q_OS_WIN
101 fileAttrib = INVALID_FILE_ATTRIBUTES;
102 fileHandle = INVALID_HANDLE_VALUE;
103 mapHandle = NULL;
104 cachedFd = -1;
105#endif
106}
107
113{
114 Q_D(QFSFileEngine);
115 d->fileEntry = QFileSystemEntry(file);
116}
117
122{
123}
124
130{
131}
132
136ProcessOpenModeResult processOpenModeFlags(QIODevice::OpenMode openMode)
137{
139 result.ok = false;
140 if ((openMode & QFile::NewOnly) && (openMode & QFile::ExistingOnly)) {
141 qWarning("NewOnly and ExistingOnly are mutually exclusive");
142 result.error = "NewOnly and ExistingOnly are mutually exclusive"_L1;
143 return result;
144 }
145
146 if ((openMode & QFile::ExistingOnly) && !(openMode & (QFile::ReadOnly | QFile::WriteOnly))) {
147 qWarning("ExistingOnly must be specified alongside ReadOnly, WriteOnly, or ReadWrite");
148 result.error =
149 "ExistingOnly must be specified alongside ReadOnly, WriteOnly, or ReadWrite"_L1;
150 return result;
151 }
152
153 // Either Append or NewOnly implies WriteOnly
154 if (openMode & (QFile::Append | QFile::NewOnly))
155 openMode |= QFile::WriteOnly;
156
157 // WriteOnly implies Truncate when ReadOnly, Append, and NewOnly are not set.
158 if ((openMode & QFile::WriteOnly) && !(openMode & (QFile::ReadOnly | QFile::Append | QFile::NewOnly)))
159 openMode |= QFile::Truncate;
160
161 result.ok = true;
162 result.openMode = openMode;
163 return result;
164}
165
170{
171 Q_D(QFSFileEngine);
172 if (d->closeFileHandle) {
173 if (d->fh) {
174 fclose(d->fh);
175 } else if (d->fd != -1) {
176 QT_CLOSE(d->fd);
177 }
178 }
179 d->unmapAll();
180}
181
186{
187 Q_D(QFSFileEngine);
188 d->init();
189 d->fileEntry = QFileSystemEntry(file);
190}
191
195bool QFSFileEngine::open(QIODevice::OpenMode openMode,
196 std::optional<QFile::Permissions> permissions)
197{
198 Q_ASSERT_X(openMode & QIODevice::Unbuffered, "QFSFileEngine::open",
199 "QFSFileEngine no longer supports buffered mode; upper layer must buffer");
200
201 Q_D(QFSFileEngine);
202 if (d->fileEntry.isEmpty()) {
203 qWarning("QFSFileEngine::open: No file name specified");
204 setError(QFile::OpenError, "No file name specified"_L1);
205 return false;
206 }
207
209 if (!res.ok) {
211 return false;
212 }
213
214 d->openMode = res.openMode;
215 d->lastFlushFailed = false;
216 d->tried_stat = 0;
217 d->fh = nullptr;
218 d->fd = -1;
219
220 return d->nativeOpen(d->openMode, permissions);
221}
222
227bool QFSFileEngine::open(QIODevice::OpenMode openMode, FILE *fh)
228{
229 return open(openMode, fh, QFile::DontCloseHandle);
230}
231
232bool QFSFileEngine::open(QIODevice::OpenMode openMode, FILE *fh, QFile::FileHandleFlags handleFlags)
233{
234 Q_ASSERT_X(openMode & QIODevice::Unbuffered, "QFSFileEngine::open",
235 "QFSFileEngine no longer supports buffered mode; upper layer must buffer");
236
237 Q_D(QFSFileEngine);
238
240 if (!res.ok) {
242 return false;
243 }
244
245 d->openMode = res.openMode;
246 d->lastFlushFailed = false;
247 d->closeFileHandle = handleFlags.testAnyFlag(QFile::AutoCloseHandle);
248 d->fileEntry.clear();
249 d->tried_stat = 0;
250 d->fd = -1;
251
252 return d->openFh(d->openMode, fh);
253}
254
258bool QFSFileEnginePrivate::openFh(QIODevice::OpenMode openMode, FILE *fh)
259{
260 Q_ASSERT_X(openMode & QIODevice::Unbuffered, "QFSFileEngine::open",
261 "QFSFileEngine no longer supports buffered mode; upper layer must buffer");
262
263 Q_Q(QFSFileEngine);
264 this->fh = fh;
265 fd = -1;
266
267 // Seek to the end when in Append mode.
269 int ret;
270 do {
271 ret = QT_FSEEK(fh, 0, SEEK_END);
272 } while (ret != 0 && errno == EINTR);
273
274 if (ret != 0) {
275 q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
277
278 this->openMode = QIODevice::NotOpen;
279 this->fh = nullptr;
280
281 return false;
282 }
283 }
284
285 return true;
286}
287
292bool QFSFileEngine::open(QIODevice::OpenMode openMode, int fd)
293{
294 return open(openMode, fd, QFile::DontCloseHandle);
295}
296
297bool QFSFileEngine::open(QIODevice::OpenMode openMode, int fd, QFile::FileHandleFlags handleFlags)
298{
299 Q_D(QFSFileEngine);
300
302 if (!res.ok) {
304 return false;
305 }
306
307 d->openMode = res.openMode;
308 d->lastFlushFailed = false;
309 d->closeFileHandle = handleFlags.testAnyFlag(QFile::AutoCloseHandle);
310 d->fileEntry.clear();
311 d->fh = nullptr;
312 d->fd = -1;
313 d->tried_stat = 0;
314
315 return d->openFd(d->openMode, fd);
316}
317
318
323bool QFSFileEnginePrivate::openFd(QIODevice::OpenMode openMode, int fd)
324{
325 Q_Q(QFSFileEngine);
326 this->fd = fd;
327 fh = nullptr;
328
329 // Seek to the end when in Append mode.
330 if (openMode & QFile::Append) {
331 QT_OFF_T ret;
332 do {
333 ret = QT_LSEEK(fd, 0, SEEK_END);
334 } while (ret == -1 && errno == EINTR);
335
336 if (ret == -1) {
337 q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
339
340 this->openMode = QIODevice::NotOpen;
341 this->fd = -1;
342
343 return false;
344 }
345 }
346
347 return true;
348}
349
354{
355 Q_D(QFSFileEngine);
356 d->openMode = QIODevice::NotOpen;
357 return d->nativeClose();
358}
359
364{
365 Q_Q(QFSFileEngine);
366 if (fd == -1 && !fh)
367 return false;
368
369 // Flush the file if it's buffered, and if the last flush didn't fail.
370 bool flushed = !fh || (!lastFlushFailed && q->flush());
371 bool closed = true;
372 tried_stat = 0;
373
374 // Close the file if we created the handle.
375 if (closeFileHandle) {
376 int ret;
377
378 if (fh) {
379 // Close buffered file.
380 ret = fclose(fh);
381 } else {
382 // Close unbuffered file.
383 ret = QT_CLOSE(fd);
384 }
385
386 // We must reset these guys regardless; calling close again after a
387 // failed close causes crashes on some systems.
388 fh = nullptr;
389 fd = -1;
390 closed = (ret == 0);
391 }
392
393 // Report errors.
394 if (!flushed || !closed) {
395 if (flushed) {
396 // If not flushed, we want the flush error to fall through.
398 }
399 return false;
400 }
401
402 return true;
403}
404
409{
410 Q_D(QFSFileEngine);
411 if ((d->openMode & QIODevice::WriteOnly) == 0) {
412 // Nothing in the write buffers, so flush succeeds in doing
413 // nothing.
414 return true;
415 }
416 return d->nativeFlush();
417}
418
423{
424 Q_D(QFSFileEngine);
425 if ((d->openMode & QIODevice::WriteOnly) == 0)
426 return true;
427 return d->nativeSyncToDisk();
428}
429
434{
435 Q_Q(QFSFileEngine);
436
437 // Never try to flush again if the last flush failed. Otherwise you can
438 // get crashes on some systems (AIX).
439 if (lastFlushFailed)
440 return false;
441
442 int ret = fflush(fh);
443
444 lastFlushFailed = (ret != 0);
446
447 if (ret != 0) {
448 q->setError(errno == ENOSPC ? QFile::ResourceError : QFile::WriteError,
450 return false;
451 }
452 return true;
453}
454
459{
460 Q_D(const QFSFileEngine);
461 return d->nativeSize();
462}
463
468{
469 if (!maps.isEmpty()) {
470 const QList<uchar*> keys = maps.keys(); // Make a copy since unmap() modifies the map.
471 for (int i = 0; i < keys.size(); ++i)
472 unmap(keys.at(i));
473 }
474}
475
476#ifndef Q_OS_WIN
481{
482 Q_Q(const QFSFileEngine);
483 const_cast<QFSFileEngine *>(q)->flush();
484
485 tried_stat = 0;
488 return 0;
489 return metaData.size();
490}
491#endif
492
497{
498 Q_D(const QFSFileEngine);
499 return d->nativePos();
500}
501
506{
507 if (fh)
508 return qint64(QT_FTELL(fh));
509 return QT_LSEEK(fd, 0, SEEK_CUR);
510}
511
516{
517 Q_D(QFSFileEngine);
518 return d->nativeSeek(pos);
519}
520
525{
526 Q_D(const QFSFileEngine);
527
528 if (time == AccessTime) {
529 // always refresh for the access time
530 d->metaData.clearFlags(QFileSystemMetaData::AccessTime);
531 }
532
533 if (d->doStat(QFileSystemMetaData::Times))
534 return d->metaData.fileTime(time);
535
536 return QDateTime();
537}
538
539
544{
545 Q_Q(QFSFileEngine);
546
547 // On Windows' stdlib implementation, the results of calling fread and
548 // fwrite are undefined if not called either in sequence, or if preceded
549 // with a call to fflush().
551 return false;
552
553 if (pos < 0 || pos != qint64(QT_OFF_T(pos)))
554 return false;
555
556 if (fh) {
557 // Buffered stdlib mode.
558 int ret;
559 do {
560 ret = QT_FSEEK(fh, QT_OFF_T(pos), SEEK_SET);
561 } while (ret != 0 && errno == EINTR);
562
563 if (ret != 0) {
565 return false;
566 }
567 } else {
568 // Unbuffered stdio mode.
569 if (QT_LSEEK(fd, QT_OFF_T(pos), SEEK_SET) == -1) {
570 qWarning("QFile::at: Cannot set file position %lld", pos);
572 return false;
573 }
574 }
575 return true;
576}
577
582{
583 Q_D(const QFSFileEngine);
584 return d->nativeHandle();
585}
586
591{
592 Q_D(QFSFileEngine);
593
594 // On Windows' stdlib implementation, the results of calling fread and
595 // fwrite are undefined if not called either in sequence, or if preceded
596 // with a call to fflush().
597 if (d->lastIOCommand != QFSFileEnginePrivate::IOReadCommand) {
598 flush();
599 d->lastIOCommand = QFSFileEnginePrivate::IOReadCommand;
600 }
601
602 return d->nativeRead(data, maxlen);
603}
604
609{
610 Q_Q(QFSFileEngine);
611
612 if (len < 0 || len != qint64(size_t(len))) {
613 q->setError(QFile::ReadError, QSystemError::stdString(EINVAL));
614 return -1;
615 }
616
617 qint64 readBytes = 0;
618 bool eof = false;
619
620 if (fh) {
621 // Buffered stdlib mode.
622
623 size_t result;
624 bool retry = true;
625 do {
626 result = fread(data + readBytes, 1, size_t(len - readBytes), fh);
627 eof = feof(fh);
628 if (retry && eof && result == 0) {
629 // On OS X, this is needed, e.g., if a file was written to
630 // through another stream since our last read. See test
631 // tst_QFile::appendAndRead
632 QT_FSEEK(fh, QT_FTELL(fh), SEEK_SET); // re-sync stream.
633 retry = false;
634 continue;
635 }
636 readBytes += result;
637 } while (!eof && (result == 0 ? errno == EINTR : readBytes < len));
638
639 } else if (fd != -1) {
640 // Unbuffered stdio mode.
641
643 do {
644 // calculate the chunk size
645 // on Windows or 32-bit no-largefile Unix, we'll need to read in chunks
646 // we limit to the size of the signed type, otherwise we could get a negative number as a result
647 quint64 wantedBytes = quint64(len) - quint64(readBytes);
648 UnsignedIOType chunkSize = std::numeric_limits<SignedIOType>::max();
649 if (chunkSize > wantedBytes)
650 chunkSize = wantedBytes;
651 result = QT_READ(fd, data + readBytes, chunkSize);
652 } while (result > 0 && (readBytes += result) < len);
653
654 eof = !(result == -1);
655 }
656
657 if (!eof && readBytes == 0) {
658 readBytes = -1;
660 }
661
662 return readBytes;
663}
664
669{
670 Q_D(QFSFileEngine);
671
672 // On Windows' stdlib implementation, the results of calling fread and
673 // fwrite are undefined if not called either in sequence, or if preceded
674 // with a call to fflush().
675 if (d->lastIOCommand != QFSFileEnginePrivate::IOReadCommand) {
676 flush();
677 d->lastIOCommand = QFSFileEnginePrivate::IOReadCommand;
678 }
679
680 return d->nativeReadLine(data, maxlen);
681}
682
687{
688 Q_Q(QFSFileEngine);
689 if (!fh)
690 return q->QAbstractFileEngine::readLine(data, maxlen);
691
692 QT_OFF_T oldPos = 0;
693#ifdef Q_OS_WIN
694 bool seq = q->isSequential();
695 if (!seq)
696#endif
697 oldPos = QT_FTELL(fh);
698
699 // QIODevice::readLine() passes maxlen - 1 to QFile::readLineData()
700 // because it has made space for the '\0' at the end of data. But fgets
701 // does the same, so we'd get two '\0' at the end - passing maxlen + 1
702 // solves this.
703 if (!fgets(data, int(maxlen + 1), fh)) {
704 if (!feof(fh))
706 return -1; // error
707 }
708
709#ifdef Q_OS_WIN
710 if (seq)
711 return qstrlen(data);
712#endif
713
714 qint64 lineLength = QT_FTELL(fh) - oldPos;
715 return lineLength > 0 ? lineLength : qstrlen(data);
716}
717
722{
723 Q_D(QFSFileEngine);
724 d->metaData.clearFlags(QFileSystemMetaData::Times);
725
726 // On Windows' stdlib implementation, the results of calling fread and
727 // fwrite are undefined if not called either in sequence, or if preceded
728 // with a call to fflush().
729 if (d->lastIOCommand != QFSFileEnginePrivate::IOWriteCommand) {
730 flush();
732 }
733
734 return d->nativeWrite(data, len);
735}
736
741{
742 Q_Q(QFSFileEngine);
743
744 if (len < 0 || len != qint64(size_t(len))) {
745 q->setError(QFile::WriteError, QSystemError::stdString(EINVAL));
746 return -1;
747 }
748
749 qint64 writtenBytes = 0;
750
751 if (len) { // avoid passing nullptr to fwrite() or QT_WRITE() (UB)
752
753 if (fh) {
754 // Buffered stdlib mode.
755
756 size_t result;
757 do {
758 result = fwrite(data + writtenBytes, 1, size_t(len - writtenBytes), fh);
759 writtenBytes += result;
760 } while (result == 0 ? errno == EINTR : writtenBytes < len);
761
762 } else if (fd != -1) {
763 // Unbuffered stdio mode.
764
766 do {
767 // calculate the chunk size
768 // on Windows or 32-bit no-largefile Unix, we'll need to read in chunks
769 // we limit to the size of the signed type, otherwise we could get a negative number as a result
770 quint64 wantedBytes = quint64(len) - quint64(writtenBytes);
771 UnsignedIOType chunkSize = std::numeric_limits<SignedIOType>::max();
772 if (chunkSize > wantedBytes)
773 chunkSize = wantedBytes;
774 result = QT_WRITE(fd, data + writtenBytes, chunkSize);
775 } while (result > 0 && (writtenBytes += result) < len);
776 }
777
778 }
779
780 if (len && writtenBytes == 0) {
781 writtenBytes = -1;
782 q->setError(errno == ENOSPC ? QFile::ResourceError : QFile::WriteError, QSystemError::stdString());
783 } else {
784 // reset the cached size, if any
786 }
787
788 return writtenBytes;
789}
790
791#ifndef QT_NO_FILESYSTEMITERATOR
796{
797 return new QFSFileEngineIterator(filters, filterNames);
798}
799
804{
805 return nullptr;
806}
807#endif // QT_NO_FILESYSTEMITERATOR
808
812QStringList QFSFileEngine::entryList(QDir::Filters filters, const QStringList &filterNames) const
813{
814 return QAbstractFileEngine::entryList(filters, filterNames);
815}
816
821{
822 Q_D(const QFSFileEngine);
823 if (d->is_sequential == 0)
824 d->is_sequential = d->nativeIsSequential() ? 1 : 2;
825 return d->is_sequential == 1;
826}
827
831#ifdef Q_OS_UNIX
833{
835 return metaData.isSequential();
836 return true;
837}
838#endif
839
844{
845 Q_D(QFSFileEngine);
846 if (extension == AtEndExtension && d->fh && isSequential())
847 return feof(d->fh);
848
849 if (extension == MapExtension) {
850 const MapExtensionOption *options = (const MapExtensionOption*)(option);
851 MapExtensionReturn *returnValue = static_cast<MapExtensionReturn*>(output);
852 returnValue->address = d->map(options->offset, options->size, options->flags);
853 return (returnValue->address != nullptr);
854 }
855 if (extension == UnMapExtension) {
856 const UnMapExtensionOption *options = (const UnMapExtensionOption*)option;
857 return d->unmap(options->address);
858 }
859
860 return false;
861}
862
867{
868 Q_D(const QFSFileEngine);
869 if (extension == AtEndExtension && d->fh && isSequential())
870 return true;
871 if (extension == FastReadLineExtension && d->fh)
872 return true;
873 if (extension == FastReadLineExtension && d->fd != -1 && isSequential())
874 return true;
876 return true;
877 return false;
878}
879
919{
921}
922
929{
931}
932
938{
940}
941
975bool QFSFileEngine::copy(const QString &copyName)
976{
977 Q_D(QFSFileEngine);
979 bool ret = QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(copyName), error);
980 if (!ret)
981 setError(QFile::CopyError, error.toString());
982 return ret;
983}
984
989{
990 Q_D(QFSFileEngine);
992 bool ret = QFileSystemEngine::removeFile(d->fileEntry, error);
993 d->metaData.clear();
994 if (!ret)
995 setError(QFile::RemoveError, error.toString());
996 return ret;
997}
998
1002bool QFSFileEngine::rename(const QString &newName)
1003{
1004 Q_D(QFSFileEngine);
1006 bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName), error);
1007 if (!ret)
1008 setError(QFile::RenameError, error.toString());
1009 return ret;
1010}
1015{
1016 Q_D(QFSFileEngine);
1019 if (!ret)
1020 setError(QFile::RenameError, error.toString());
1021 return ret;
1022}
1023
1027bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories,
1028 std::optional<QFile::Permissions> permissions) const
1029{
1030 return QFileSystemEngine::createDirectory(QFileSystemEntry(name), createParentDirectories,
1031 permissions);
1032}
1033
1037bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const
1038{
1039 return QFileSystemEngine::removeDirectory(QFileSystemEntry(name), recurseParentDirectories);
1040}
1041
1042
1050{
1052}
1053
1067
1068#endif // QT_NO_FSFILEENGINE
The QAbstractFileEngineIterator class provides an iterator interface for custom file engines.
\inmodule QtCore \reentrant
FileTime
These are used by the fileTime() function.
void setError(QFile::FileError error, const QString &str)
Sets the error type to error, and the error string to errorString.
virtual QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const
Requests that a list of all the files matching the filters list based on the filterNames in the file ...
QFile::FileError error() const
Returns the QFile::FileError that resulted from the last failed operation.
\inmodule QtCore\reentrant
Definition qdatetime.h:257
qint64 readFdFh(char *data, qint64 maxlen)
bool openFd(QIODevice::OpenMode flags, int fd)
Opens the file descriptor fd to the file engine, using the open mode flags.
QHash< uchar *, StartAndLength > maps
qint64 writeFdFh(const char *data, qint64 len)
QIODevice::OpenMode openMode
qint64 sizeFdFh() const
bool doStat(QFileSystemMetaData::MetaDataFlags flags=QFileSystemMetaData::PosixStatFlags) const
QFileSystemMetaData metaData
bool isSequentialFdFh() const
qint64 readLineFdFh(char *data, qint64 maxlen)
bool openFh(QIODevice::OpenMode flags, FILE *fh)
Opens the file handle fh using the open mode flags.
LastIOCommand lastIOCommand
\inmodule QtCore
qint64 read(char *data, qint64 maxlen) override
\reimp
qint64 write(const char *data, qint64 len) override
\reimp
bool rmdir(const QString &dirName, bool recurseParentDirectories) const override
\reimp
bool rename(const QString &newName) override
\reimp
static QString tempPath()
Returns the temporary path (i.e., a path in which it is safe to store temporary files).
qint64 pos() const override
\reimp
bool renameOverwrite(const QString &newName) override
\reimp
bool close() override
\reimp
bool syncToDisk() override
\reimp
QFSFileEngine()
Constructs a QFSFileEngine.
qint64 size() const override
\reimp
static QString rootPath()
Returns the root path.
QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const override
QDateTime fileTime(FileTime time) const override
\reimp
bool isSequential() const override
\reimp
bool open(QIODevice::OpenMode openMode, std::optional< QFile::Permissions > permissions) override
\reimp
void setFileName(const QString &file) override
\reimp
bool seek(qint64) override
\reimp
static bool setCurrentPath(const QString &path)
Sets the current path (e.g., for QDir), to path.
bool mkdir(const QString &dirName, bool createParentDirectories, std::optional< QFile::Permissions > permissions) const override
\reimp
bool copy(const QString &newName) override
For Windows or Apple platforms, copy the file to file copyName.
bool supportsExtension(Extension extension) const override
\reimp
int handle() const override
\reimp
Iterator * endEntryList() override
bool extension(Extension extension, const ExtensionOption *option=nullptr, ExtensionReturn *output=nullptr) override
\reimp
qint64 readLine(char *data, qint64 maxlen) override
\reimp
static QString homePath()
Returns the home path of the current user.
bool remove() override
\reimp
Iterator * beginEntryList(QDir::Filters filters, const QStringList &filterNames) override
~QFSFileEngine()
Destructs the QFSFileEngine.
bool flush() override
\reimp
static bool setCurrentPath(const QFileSystemEntry &entry)
static bool copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
static bool renameOverwriteFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
static bool createDirectory(const QFileSystemEntry &entry, bool createParents, std::optional< QFile::Permissions > permissions=std::nullopt)
static bool renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
static bool removeFile(const QFileSystemEntry &entry, QSystemError &error)
static bool removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents)
void clearFlags(MetaDataFlags flags=AllMetaDataFlags)
Definition qlist.h:74
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
static Q_CORE_EXPORT QString stdString(int errorCode=-1)
void extension()
[6]
Definition dialogs.cpp:230
Combined button and popup list for selecting options.
size_t qstrlen(const char *str)
#define QT_READ
#define QT_CLOSE
#define QT_WRITE
#define INVALID_FILE_ATTRIBUTES
size_t UnsignedIOType
ssize_t SignedIOType
ProcessOpenModeResult processOpenModeFlags(QIODevice::OpenMode openMode)
Q_CORE_EXPORT ProcessOpenModeResult processOpenModeFlags(QIODevice::OpenMode mode)
#define qWarning
Definition qlogging.h:162
return ret
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint64 GLenum GLint fd
GLuint name
GLuint res
GLenum GLsizei len
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLsizei const GLchar *const * path
GLuint64EXT * result
[6]
GLuint GLenum option
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
unsigned long long quint64
Definition qtypes.h:56
long long qint64
Definition qtypes.h:55
QT_BEGIN_NAMESPACE typedef uchar * output
QFile file
[0]
QStringList keys
const QStringList filters({"Image files (*.png *.xpm *.jpg)", "Text files (*.txt)", "Any files (*)" })
[6]