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