Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qfiledevice.cpp
Go to the documentation of this file.
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// Qt-Security score:significant reason:trivial-parsing-only
4
5#include "qplatformdefs.h"
6#include "qfiledevice.h"
9
10#ifdef QT_NO_QOBJECT
11#define tr(X) QString::fromLatin1(X)
12#endif
13
15
16#ifndef QFILE_WRITEBUFFER_SIZE
17#define QFILE_WRITEBUFFER_SIZE 16384
18#endif
19
20QFileDevicePrivate::QFileDevicePrivate()
21 : cachedSize(0),
22 error(QFile::NoError), lastWasWrite(false)
23{
24 writeBufferChunkSize = QFILE_WRITEBUFFER_SIZE;
25}
26
28
29QAbstractFileEngine *QFileDevicePrivate::engine() const
30{
31 if (!fileEngine)
32 fileEngine = std::make_unique<QFSFileEngine>();
33 return fileEngine.get();
34}
35
36void QFileDevicePrivate::setError(QFileDevice::FileError err)
37{
38 error = err;
39 errorString.clear();
40}
41
42void QFileDevicePrivate::setError(QFileDevice::FileError err, const QString &errStr)
43{
44 error = err;
45 errorString = errStr;
46}
47
48void QFileDevicePrivate::setError(QFileDevice::FileError err, int errNum)
49{
50 error = err;
51 errorString = qt_error_string(errNum);
52}
53
54/*!
55 \enum QFileDevice::FileError
56
57 This enum describes the errors that may be returned by the error()
58 function.
59
60 \value NoError No error occurred.
61 \value ReadError An error occurred when reading from the file.
62 \value WriteError An error occurred when writing to the file.
63 \value FatalError A fatal error occurred.
64 \value ResourceError Out of resources (e.g., too many open files, out of memory, etc.)
65 \value OpenError The file could not be opened.
66 \value AbortError The operation was aborted.
67 \value TimeOutError A timeout occurred.
68 \value UnspecifiedError An unspecified error occurred.
69 \value RemoveError The file could not be removed.
70 \value RenameError The file could not be renamed.
71 \value PositionError The position in the file could not be changed.
72 \value ResizeError The file could not be resized.
73 \value PermissionsError The file could not be accessed.
74 \value CopyError The file could not be copied.
75*/
76
77/*!
78 \enum QFileDevice::Permission
79
80 This enum is used by the permission() function to report the
81 permissions and ownership of a file. The values may be OR-ed
82 together to test multiple permissions and ownership values.
83
84 \value ReadOwner The file is readable by the owner of the file.
85 \value WriteOwner The file is writable by the owner of the file.
86 \value ExeOwner The file is executable by the owner of the file.
87 \value ReadUser The file is readable by the user.
88 \value WriteUser The file is writable by the user.
89 \value ExeUser The file is executable by the user.
90 \value ReadGroup The file is readable by the group.
91 \value WriteGroup The file is writable by the group.
92 \value ExeGroup The file is executable by the group.
93 \value ReadOther The file is readable by others.
94 \value WriteOther The file is writable by others.
95 \value ExeOther The file is executable by others.
96
97 \warning Because of differences in the platforms supported by Qt,
98 the semantics of ReadUser, WriteUser and ExeUser are
99 platform-dependent: On Unix, the rights of the owner of the file
100 are returned and on Windows the rights of the current user are
101 returned. This behavior might change in a future Qt version.
102
103 \note On NTFS file systems, ownership and permissions checking is
104 disabled by default for performance reasons. To enable it,
105 include the following line:
106
107 \snippet ntfsp.cpp 0
108
109 Permission checking is then turned on and off by incrementing and
110 decrementing \c qt_ntfs_permission_lookup by 1.
111
112 \snippet ntfsp.cpp 1
113
114 \note Since this is a non-atomic global variable, it is only safe
115 to increment or decrement \c qt_ntfs_permission_lookup before any
116 threads other than the main thread have started or after every thread
117 other than the main thread has ended.
118
119 \note From Qt 6.6 the variable \c qt_ntfs_permission_lookup is
120 deprecated. Please use the following alternatives.
121
122 The safe and easy way to manage permission checks is to use the RAII class
123 \c QNtfsPermissionCheckGuard.
124
125 \snippet ntfsp.cpp raii
126
127 If you need more fine-grained control, it is possible to manage the permission
128 with the following functions instead:
129
130 \snippet ntfsp.cpp free-funcs
131
132*/
133
134//************* QFileDevice
135
136/*!
137 \class QFileDevice
138 \inmodule QtCore
139 \since 5.0
140
141 \brief The QFileDevice class provides an interface for reading from and writing to open files.
142
143 \ingroup io
144
145 \reentrant
146
147 QFileDevice is the base class for I/O devices that can read and write text and binary files
148 and \l{The Qt Resource System}{resources}. QFile offers the main functionality,
149 QFileDevice serves as a base class for sharing functionality with other file devices such
150 as QSaveFile, by providing all the operations that can be done on files that have
151 been opened by QFile or QSaveFile.
152
153 \sa QFile, QSaveFile
154*/
155
156/*!
157 \enum QFileDevice::FileHandleFlag
158
159 This enum is used when opening a file to specify additional
160 options which only apply to files and not to a generic
161 QIODevice.
162
163 \value AutoCloseHandle The file handle passed into open() should be
164 closed by close(), the default behavior is that close just flushes
165 the file and the application is responsible for closing the file handle.
166 When opening a file by name, this flag is ignored as Qt always owns the
167 file handle and must close it.
168 \value DontCloseHandle If not explicitly closed, the underlying file
169 handle is left open when the QFile object is destroyed.
170 */
171
172/*!
173 \macro QT_USE_NODISCARD_FILE_OPEN
174 \macro QT_NO_USE_NODISCARD_FILE_OPEN
175 \relates QFileDevice
176 \since 6.8
177
178 File-related I/O classes (such as QFile, QSaveFile, QTemporaryFile)
179 have an \c{open()} method to open the file they act upon. It is
180 important to check the return value of the call to \c{open()}
181 before proceeding with reading or writing data into the file.
182
183 For this reason, starting with Qt 6.8, some overloads of \c{open()}
184 have been marked with the \c{[[nodiscard]]} attribute. Since this
185 change may raise warnings in existing codebases, user code can
186 opt-in or opt-out from having the attribute applied by defining
187 certain macros:
188
189 \list
190 \li If the \c{QT_USE_NODISCARD_FILE_OPEN} macro is defined,
191 overloads of \c{open()} are marked as \c{[[nodiscard]]}.
192 \li If the \c{QT_NO_USE_NODISCARD_FILE_OPEN} is defined, the
193 overloads of \c{open()} are \e{not} marked as \c{[[nodiscard]]}.
194 \li If neither macro is defined, then the default up to and
195 including Qt 6.9 is not to have the attribute. Starting from Qt 6.10,
196 the attribute is automatically applied.
197 \li If both macros are defined, the program is ill-formed.
198 \endlist
199*/
200
201#ifdef QT_NO_QOBJECT
202QFileDevice::QFileDevice()
203 : QIODevice(*new QFileDevicePrivate)
204{
205}
206QFileDevice::QFileDevice(QFileDevicePrivate &dd)
207 : QIODevice(dd)
208{
209}
210#else
211/*!
212 \internal
213*/
214QFileDevice::QFileDevice()
215 : QIODevice(*new QFileDevicePrivate, nullptr)
216{
217}
218/*!
219 \internal
220*/
221QFileDevice::QFileDevice(QObject *parent)
222 : QIODevice(*new QFileDevicePrivate, parent)
223{
224}
225/*!
226 \internal
227*/
228QFileDevice::QFileDevice(QFileDevicePrivate &dd, QObject *parent)
229 : QIODevice(dd, parent)
230{
231}
232#endif
233
234/*!
235 Destroys the file device, closing it if necessary.
236*/
237QFileDevice::~QFileDevice()
238{
239 close();
240}
241
242/*!
243 Returns \c true if the file can only be manipulated sequentially;
244 otherwise returns \c false.
245
246 Most files support random-access, but some special files may not.
247
248 \sa QIODevice::isSequential()
249*/
250bool QFileDevice::isSequential() const
251{
252 Q_D(const QFileDevice);
253 return d->fileEngine && d->fileEngine->isSequential();
254}
255
256/*!
257 Returns the file handle of the file.
258
259 This is a small positive integer, suitable for use with C library
260 functions such as \c fdopen() and \c fcntl(). On systems that use file
261 descriptors for sockets (i.e. Unix systems, but not Windows) the handle
262 can be used with QSocketNotifier as well.
263
264 If the file is not open, or there is an error, handle() returns -1.
265
266 \sa QSocketNotifier
267*/
268int QFileDevice::handle() const
269{
270 Q_D(const QFileDevice);
271 if (!isOpen() || !d->fileEngine)
272 return -1;
273
274 return d->fileEngine->handle();
275}
276
277/*!
278 Returns the name of the file.
279 The default implementation in QFileDevice returns a null string.
280*/
281QString QFileDevice::fileName() const
282{
283 return QString();
284}
285
286/*!
287 Flushes any buffered data to the file. Returns \c true if successful;
288 otherwise returns \c false.
289*/
290bool QFileDevice::flush()
291{
292 Q_D(QFileDevice);
293 if (!d->fileEngine) {
294 qWarning("QFileDevice::flush: No file engine. Is IODevice open?");
295 return false;
296 }
297
298 if (!d->writeBuffer.isEmpty()) {
299 qint64 size = d->writeBuffer.nextDataBlockSize();
300 qint64 written = d->fileEngine->write(d->writeBuffer.readPointer(), size);
301 if (written > 0)
302 d->writeBuffer.free(written);
303 if (written != size) {
304 QFileDevice::FileError err = d->fileEngine->error();
305 if (err == QFileDevice::UnspecifiedError)
306 err = QFileDevice::WriteError;
307 d->setError(err, d->fileEngine->errorString());
308 return false;
309 }
310 }
311
312 if (!d->fileEngine->flush()) {
313 QFileDevice::FileError err = d->fileEngine->error();
314 if (err == QFileDevice::UnspecifiedError)
315 err = QFileDevice::WriteError;
316 d->setError(err, d->fileEngine->errorString());
317 return false;
318 }
319 return true;
320}
321
322/*!
323 Calls QFileDevice::flush() and closes the file. Errors from flush are ignored.
324
325 \sa QIODevice::close()
326*/
327void QFileDevice::close()
328{
329 Q_D(QFileDevice);
330 if (!isOpen())
331 return;
332 bool flushed = flush();
333 QIODevice::close();
334
335 // reset write buffer
336 d->lastWasWrite = false;
337 d->writeBuffer.clear();
338
339 // reset cached size
340 d->cachedSize = 0;
341
342 // If flush() succeeded but close() failed, copy its error condition;
343 // otherwise, keep the earlier flush() error.
344 if (d->fileEngine->close() && flushed)
345 unsetError();
346 else if (flushed)
347 d->setError(d->fileEngine->error(), d->fileEngine->errorString());
348}
349
350/*!
351 \reimp
352*/
353qint64 QFileDevice::pos() const
354{
355 return QIODevice::pos();
356}
357
358/*!
359 Returns \c true if the end of the file has been reached; otherwise returns
360 false.
361
362 For regular empty files on Unix (e.g. those in \c /proc), this function
363 returns \c true, since the file system reports that the size of such a file is
364 0. Therefore, you should not depend on atEnd() when reading data from such a
365 file, but rather call read() until no more data can be read.
366*/
367bool QFileDevice::atEnd() const
368{
369 Q_D(const QFileDevice);
370
371 // If there's buffered data left, we're not at the end.
372 if (!d->isBufferEmpty())
373 return false;
374
375 if (!isOpen())
376 return true;
377
378 if (!d->ensureFlushed())
379 return false;
380
381 // If the file engine knows best, say what it says.
382 if (d->fileEngine->supportsExtension(QAbstractFileEngine::AtEndExtension)) {
383 // Check if the file engine supports AtEndExtension, and if it does,
384 // check if the file engine claims to be at the end.
385 return d->fileEngine->atEnd();
386 }
387
388 // if it looks like we are at the end, or if size is not cached,
389 // fall through to bytesAvailable() to make sure.
390 if (pos() < d->cachedSize)
391 return false;
392
393 // Fall back to checking how much is available (will stat files).
394 return bytesAvailable() == 0;
395}
396
397/*!
398 \fn bool QFileDevice::seek(qint64 pos)
399
400 For random-access devices, this function sets the current position
401 to \a pos, returning true on success, or false if an error occurred.
402 For sequential devices, the default behavior is to do nothing and
403 return false.
404
405 Seeking beyond the end of a file:
406 If the position is beyond the end of a file, then seek() will not
407 immediately extend the file. If a write is performed at this position,
408 then the file will be extended. The content of the file between the
409 previous end of file and the newly written data is UNDEFINED and
410 varies between platforms and file systems.
411*/
412bool QFileDevice::seek(qint64 off)
413{
414 Q_D(QFileDevice);
415 if (!isOpen()) {
416 qWarning("QFileDevice::seek: IODevice is not open");
417 return false;
418 }
419
420 if (!d->ensureFlushed())
421 return false;
422
423 if (!d->fileEngine->seek(off) || !QIODevice::seek(off)) {
424 QFileDevice::FileError err = d->fileEngine->error();
425 if (err == QFileDevice::UnspecifiedError)
426 err = QFileDevice::PositionError;
427 d->setError(err, d->fileEngine->errorString());
428 return false;
429 }
430 unsetError();
431 return true;
432}
433
434/*!
435 \reimp
436*/
437qint64 QFileDevice::readLineData(char *data, qint64 maxlen)
438{
439 Q_D(QFileDevice);
440 if (!d->ensureFlushed())
441 return -1;
442
443 qint64 read;
444 if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) {
445 read = d->fileEngine->readLine(data, maxlen);
446 } else {
447 // Fall back to QIODevice's readLine implementation if the engine
448 // cannot do it faster.
449 read = QIODevice::readLineData(data, maxlen);
450 }
451
452 if (read < maxlen) {
453 // failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
454 d->cachedSize = 0;
455 }
456
457 return read;
458}
459
460/*!
461 \reimp
462*/
463qint64 QFileDevice::readData(char *data, qint64 len)
464{
465 Q_D(QFileDevice);
466 if (!len)
467 return 0;
468 unsetError();
469 if (!d->ensureFlushed())
470 return -1;
471
472 const qint64 read = d->fileEngine->read(data, len);
473 if (read < 0) {
474 QFileDevice::FileError err = d->fileEngine->error();
475 if (err == QFileDevice::UnspecifiedError)
476 err = QFileDevice::ReadError;
477 d->setError(err, d->fileEngine->errorString());
478 }
479
480 if (read < len) {
481 // failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
482 d->cachedSize = 0;
483 }
484
485 return read;
486}
487
488/*!
489 \internal
490*/
492{
493#ifdef QT_NO_QOBJECT
494 return QIODevicePrivate::putCharHelper(c);
495#else
496
497 // Cutoff for code that doesn't only touch the buffer.
498 qint64 writeBufferSize = writeBuffer.size();
499 if ((openMode & QIODevice::Unbuffered) || writeBufferSize + 1 >= writeBufferChunkSize
500#ifdef Q_OS_WIN
501 || ((openMode & QIODevice::Text) && c == '\n'
502 && writeBufferSize + 2 >= writeBufferChunkSize)
503#endif
504 ) {
505 return QIODevicePrivate::putCharHelper(c);
506 }
507
508 if (!(openMode & QIODevice::WriteOnly)) {
509 if (openMode == QIODevice::NotOpen)
510 qWarning("QIODevice::putChar: Closed device");
511 else
512 qWarning("QIODevice::putChar: ReadOnly device");
513 return false;
514 }
515
516 // Make sure the device is positioned correctly.
517 const bool sequential = isSequential();
518 if (pos != devicePos && !sequential && !q_func()->seek(pos))
519 return false;
520
521 lastWasWrite = true;
522
523 int len = 1;
524#ifdef Q_OS_WIN
525 if ((openMode & QIODevice::Text) && c == '\n') {
526 ++len;
527 *writeBuffer.reserve(1) = '\r';
528 }
529#endif
530
531 // Write to buffer.
532 *writeBuffer.reserve(1) = c;
533
534 if (!sequential) {
535 pos += len;
536 devicePos += len;
537 if (!buffer.isEmpty())
538 buffer.skip(len);
539 }
540
541 return true;
542#endif
543}
544
545/*!
546 \reimp
547*/
548qint64 QFileDevice::writeData(const char *data, qint64 len)
549{
550 Q_D(QFileDevice);
551 unsetError();
552 d->lastWasWrite = true;
553 bool buffered = !(d->openMode & Unbuffered);
554
555 // Flush buffered data if this read will overflow.
556 if (buffered && (d->writeBuffer.size() + len) > d->writeBufferChunkSize) {
557 if (!flush())
558 return -1;
559 }
560
561 // Write directly to the engine if the block size is larger than
562 // the write buffer size.
563 if (!buffered || len > d->writeBufferChunkSize) {
564 const qint64 ret = d->fileEngine->write(data, len);
565 if (ret < 0) {
566 QFileDevice::FileError err = d->fileEngine->error();
567 if (err == QFileDevice::UnspecifiedError)
568 err = QFileDevice::WriteError;
569 d->setError(err, d->fileEngine->errorString());
570 }
571 return ret;
572 }
573
574 // Write to the buffer.
575 d->writeBuffer.append(data, len);
576 return len;
577}
578
579/*!
580 Returns the file error status.
581
582 The I/O device status returns an error code. For example, if open()
583 returns \c false, or a read/write operation returns -1, this function can
584 be called to find out the reason why the operation failed.
585
586 \sa unsetError()
587*/
588QFileDevice::FileError QFileDevice::error() const
589{
590 Q_D(const QFileDevice);
591 return d->error;
592}
593
594/*!
595 Sets the file's error to QFileDevice::NoError.
596
597 \sa error()
598*/
599void QFileDevice::unsetError()
600{
601 Q_D(QFileDevice);
602 d->setError(QFileDevice::NoError);
603}
604
605/*!
606 Returns the size of the file.
607
608 For regular empty files on Unix (e.g. those in \c /proc), this function
609 returns 0; the contents of such a file are generated on demand in response
610 to you calling read().
611*/
612qint64 QFileDevice::size() const
613{
614 Q_D(const QFileDevice);
615 if (!d->ensureFlushed())
616 return 0;
617 d->cachedSize = d->engine()->size();
618 return d->cachedSize;
619}
620
621/*!
622 Sets the file size (in bytes) \a sz. Returns \c true if the
623 resize succeeds; false otherwise. If \a sz is larger than the file
624 currently is, the new bytes will be set to 0; if \a sz is smaller, the
625 file is simply truncated.
626
627 \warning This function can fail if the file doesn't exist.
628
629 \sa size()
630*/
631bool QFileDevice::resize(qint64 sz)
632{
633 Q_D(QFileDevice);
634 if (!d->ensureFlushed())
635 return false;
636 d->engine();
637 if (isOpen() && d->fileEngine->pos() > sz)
638 seek(sz);
639 if (d->fileEngine->setSize(sz)) {
640 unsetError();
641 d->cachedSize = sz;
642 return true;
643 }
644 d->cachedSize = 0;
645 d->setError(QFile::ResizeError, d->fileEngine->errorString());
646 return false;
647}
648
649/*!
650 Returns the complete OR-ed together combination of
651 QFile::Permission for the file.
652
653 \sa setPermissions()
654*/
655QFile::Permissions QFileDevice::permissions() const
656{
657 Q_D(const QFileDevice);
658 QAbstractFileEngine::FileFlags perms = d->engine()->fileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask;
659 return QFile::Permissions::fromInt(perms.toInt()); //ewww
660}
661
662/*!
663 Sets the permissions for the file to the \a permissions specified.
664 Returns \c true if successful, or \c false if the permissions cannot be
665 modified.
666
667 \warning This function does not manipulate ACLs, which may limit its
668 effectiveness.
669
670 \sa permissions()
671*/
672bool QFileDevice::setPermissions(Permissions permissions)
673{
674 Q_D(QFileDevice);
675 if (d->engine()->setPermissions(permissions.toInt())) {
676 unsetError();
677 return true;
678 }
679 d->setError(QFile::PermissionsError, d->fileEngine->errorString());
680 return false;
681}
682
683/*!
684 \enum QFileDevice::MemoryMapFlag
685 \since 4.4
686
687 This enum describes special options that may be used by the map()
688 function.
689
690 \value NoOptions No options.
691 \value MapPrivateOption The mapped memory will be private, so any
692 modifications will not be visible to other processes and will not
693 be written to disk. Any such modifications will be lost when the
694 memory is unmapped. It is unspecified whether modifications made
695 to the file made after the mapping is created will be visible through
696 the mapped memory. This enum value was introduced in Qt 5.4.
697*/
698
699/*!
700 Maps \a size bytes of the file into memory starting at \a offset. A file
701 should be open for a map to succeed but the file does not need to stay
702 open after the memory has been mapped. When the QFile is destroyed
703 or a new file is opened with this object, any maps that have not been
704 unmapped will automatically be unmapped.
705
706 The mapping will have the same open mode as the file (read and/or write),
707 except when using MapPrivateOption, in which case it is always possible
708 to write to the mapped memory.
709
710 Any mapping options can be passed through \a flags.
711
712 Returns a pointer to the memory or \nullptr if there is an error.
713
714 \sa unmap()
715 */
716uchar *QFileDevice::map(qint64 offset, qint64 size, MemoryMapFlags flags)
717{
718 Q_D(QFileDevice);
719 if (d->engine()
720 && d->fileEngine->supportsExtension(QAbstractFileEngine::MapExtension)) {
721 unsetError();
722 uchar *address = d->fileEngine->map(offset, size, flags);
723 if (address == nullptr)
724 d->setError(d->fileEngine->error(), d->fileEngine->errorString());
725 return address;
726 }
727 return nullptr;
728}
729
730/*!
731 Unmaps the memory \a address.
732
733 Returns \c true if the unmap succeeds; false otherwise.
734
735 \sa map()
736 */
737bool QFileDevice::unmap(uchar *address)
738{
739 Q_D(QFileDevice);
740 if (d->engine()
741 && d->fileEngine->supportsExtension(QAbstractFileEngine::UnMapExtension)) {
742 unsetError();
743 bool success = d->fileEngine->unmap(address);
744 if (!success)
745 d->setError(d->fileEngine->error(), d->fileEngine->errorString());
746 return success;
747 }
748 d->setError(PermissionsError, tr("No file engine available or engine does not support UnMapExtension"));
749 return false;
750}
751
752/*!
753 \enum QFileDevice::FileTime
754 \since 5.10
755
756 This enum is used by the fileTime() and setFileTime() functions.
757
758 \value FileAccessTime When the file was most recently accessed
759 (e.g. read or written to).
760 \value FileBirthTime When the file was created (may not be not
761 supported on UNIX).
762 \value FileMetadataChangeTime When the file's metadata was last changed.
763 \value FileModificationTime When the file was most recently modified.
764
765 \sa setFileTime(), fileTime(), QFileInfo::fileTime()
766*/
767
768/*!
769 \since 5.10
770 Returns the file time specified by \a time.
771 If the time cannot be determined return QDateTime() (an invalid
772 date time).
773
774 \sa setFileTime(), FileTime, QDateTime::isValid()
775*/
776QDateTime QFileDevice::fileTime(QFileDevice::FileTime time) const
777{
778 Q_D(const QFileDevice);
779
780 if (d->engine())
781 return d->engine()->fileTime(time);
782
783 return QDateTime();
784}
785
786/*!
787 \since 5.10
788 Sets the file time specified by \a fileTime to \a newDate, returning true
789 if successful; otherwise returns false.
790
791 \note The file must be open to use this function.
792
793 \sa fileTime(), FileTime
794*/
795bool QFileDevice::setFileTime(const QDateTime &newDate, QFileDevice::FileTime fileTime)
796{
797 Q_D(QFileDevice);
798
799 if (!d->engine()) {
800 d->setError(QFileDevice::UnspecifiedError, tr("No file engine available"));
801 return false;
802 }
803
804 if (!d->fileEngine->setFileTime(newDate, fileTime)) {
805 d->setError(d->fileEngine->error(), d->fileEngine->errorString());
806 return false;
807 }
808
809 unsetError();
810 return true;
811}
812
813QT_END_NAMESPACE
814
815#ifndef QT_NO_QOBJECT
816#include "moc_qfiledevice.cpp"
817#endif
void setError(QFileDevice::FileError err, int errNum)
bool putCharHelper(char c) override
virtual QAbstractFileEngine * engine() const
void setError(QFileDevice::FileError err)
void setError(QFileDevice::FileError err, const QString &errorString)
#define QFILE_WRITEBUFFER_SIZE