1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2017 Intel Corporation.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "qplatformdefs.h"
42#include "qdebug.h"
43#include "qfile.h"
44#include "qfsfileengine_p.h"
45#include "qtemporaryfile.h"
46#include "qtemporaryfile_p.h"
47#include "qlist.h"
48#include "qfileinfo.h"
49#include "private/qiodevice_p.h"
50#include "private/qfile_p.h"
51#include "private/qfilesystemengine_p.h"
52#include "private/qsystemerror_p.h"
53#include "private/qtemporaryfile_p.h"
54#if defined(QT_BUILD_CORE_LIB)
55# include "qcoreapplication.h"
56#endif
57
58#include <private/qmemory_p.h>
59
60#ifdef QT_NO_QOBJECT
61#define tr(X) QString::fromLatin1(X)
62#endif
63
64QT_BEGIN_NAMESPACE
65
66Q_DECL_COLD_FUNCTION
67static bool file_already_open(QFile &file, const char *where = nullptr)
68{
69 qWarning("QFile::%s: File (%ls) already open", where ? where : "open", qUtf16Printable(file.fileName()));
70 return false;
71}
72
73//************* QFilePrivate
74QFilePrivate::QFilePrivate()
75{
76}
77
78QFilePrivate::~QFilePrivate()
79{
80}
81
82bool
83QFilePrivate::openExternalFile(int flags, int fd, QFile::FileHandleFlags handleFlags)
84{
85#ifdef QT_NO_FSFILEENGINE
86 Q_UNUSED(flags);
87 Q_UNUSED(fd);
88 return false;
89#else
90 auto fs = qt_make_unique<QFSFileEngine>();
91 auto fe = fs.get();
92 fileEngine = std::move(fs);
93 return fe->open(QIODevice::OpenMode(flags), fd, handleFlags);
94#endif
95}
96
97bool
98QFilePrivate::openExternalFile(int flags, FILE *fh, QFile::FileHandleFlags handleFlags)
99{
100#ifdef QT_NO_FSFILEENGINE
101 Q_UNUSED(flags);
102 Q_UNUSED(fh);
103 return false;
104#else
105 auto fs = qt_make_unique<QFSFileEngine>();
106 auto fe = fs.get();
107 fileEngine = std::move(fs);
108 return fe->open(QIODevice::OpenMode(flags), fh, handleFlags);
109#endif
110}
111
112QAbstractFileEngine *QFilePrivate::engine() const
113{
114 if (!fileEngine)
115 fileEngine.reset(QAbstractFileEngine::create(fileName));
116 return fileEngine.get();
117}
118
119//************* QFile
120
121/*!
122 \class QFile
123 \inmodule QtCore
124 \brief The QFile class provides an interface for reading from and writing to files.
125
126 \ingroup io
127
128 \reentrant
129
130 QFile is an I/O device for reading and writing text and binary
131 files and \l{The Qt Resource System}{resources}. A QFile may be
132 used by itself or, more conveniently, with a QTextStream or
133 QDataStream.
134
135 The file name is usually passed in the constructor, but it can be
136 set at any time using setFileName(). QFile expects the file
137 separator to be '/' regardless of operating system. The use of
138 other separators (e.g., '\\') is not supported.
139
140 You can check for a file's existence using exists(), and remove a
141 file using remove(). (More advanced file system related operations
142 are provided by QFileInfo and QDir.)
143
144 The file is opened with open(), closed with close(), and flushed
145 with flush(). Data is usually read and written using QDataStream
146 or QTextStream, but you can also call the QIODevice-inherited
147 functions read(), readLine(), readAll(), write(). QFile also
148 inherits getChar(), putChar(), and ungetChar(), which work one
149 character at a time.
150
151 The size of the file is returned by size(). You can get the
152 current file position using pos(), or move to a new file position
153 using seek(). If you've reached the end of the file, atEnd()
154 returns \c true.
155
156 \section1 Reading Files Directly
157
158 The following example reads a text file line by line:
159
160 \snippet file/file.cpp 0
161
162 The QIODevice::Text flag passed to open() tells Qt to convert
163 Windows-style line terminators ("\\r\\n") into C++-style
164 terminators ("\\n"). By default, QFile assumes binary, i.e. it
165 doesn't perform any conversion on the bytes stored in the file.
166
167 \section1 Using Streams to Read Files
168
169 The next example uses QTextStream to read a text file
170 line by line:
171
172 \snippet file/file.cpp 1
173
174 QTextStream takes care of converting the 8-bit data stored on
175 disk into a 16-bit Unicode QString. By default, it assumes that
176 the user system's local 8-bit encoding is used (e.g., UTF-8
177 on most unix based operating systems; see QTextCodec::codecForLocale() for
178 details). This can be changed using \l QTextStream::setCodec().
179
180 To write text, we can use operator<<(), which is overloaded to
181 take a QTextStream on the left and various data types (including
182 QString) on the right:
183
184 \snippet file/file.cpp 2
185
186 QDataStream is similar, in that you can use operator<<() to write
187 data and operator>>() to read it back. See the class
188 documentation for details.
189
190 When you use QFile, QFileInfo, and QDir to access the file system
191 with Qt, you can use Unicode file names. On Unix, these file
192 names are converted to an 8-bit encoding. If you want to use
193 standard C++ APIs (\c <cstdio> or \c <iostream>) or
194 platform-specific APIs to access files instead of QFile, you can
195 use the encodeName() and decodeName() functions to convert
196 between Unicode file names and 8-bit file names.
197
198 On Unix, there are some special system files (e.g. in \c /proc) for which
199 size() will always return 0, yet you may still be able to read more data
200 from such a file; the data is generated in direct response to you calling
201 read(). In this case, however, you cannot use atEnd() to determine if
202 there is more data to read (since atEnd() will return true for a file that
203 claims to have size 0). Instead, you should either call readAll(), or call
204 read() or readLine() repeatedly until no more data can be read. The next
205 example uses QTextStream to read \c /proc/modules line by line:
206
207 \snippet file/file.cpp 3
208
209 \section1 Signals
210
211 Unlike other QIODevice implementations, such as QTcpSocket, QFile does not
212 emit the aboutToClose(), bytesWritten(), or readyRead() signals. This
213 implementation detail means that QFile is not suitable for reading and
214 writing certain types of files, such as device files on Unix platforms.
215
216 \section1 Platform Specific Issues
217
218 File permissions are handled differently on Unix-like systems and
219 Windows. In a non \l{QIODevice::isWritable()}{writable}
220 directory on Unix-like systems, files cannot be created. This is not always
221 the case on Windows, where, for instance, the 'My Documents'
222 directory usually is not writable, but it is still possible to
223 create files in it.
224
225 Qt's understanding of file permissions is limited, which affects especially
226 the \l QFile::setPermissions() function. On Windows, Qt will set only the
227 legacy read-only flag, and that only when none of the Write* flags are
228 passed. Qt does not manipulate access control lists (ACLs), which makes this
229 function mostly useless for NTFS volumes. It may still be of use for USB
230 sticks that use VFAT file systems. POSIX ACLs are not manipulated, either.
231
232 \sa QTextStream, QDataStream, QFileInfo, QDir, {The Qt Resource System}
233*/
234
235#ifdef QT_NO_QOBJECT
236QFile::QFile()
237 : QFileDevice(*new QFilePrivate)
238{
239}
240QFile::QFile(const QString &name)
241 : QFileDevice(*new QFilePrivate)
242{
243 d_func()->fileName = name;
244}
245QFile::QFile(QFilePrivate &dd)
246 : QFileDevice(dd)
247{
248}
249#else
250/*!
251 Constructs a QFile object.
252*/
253QFile::QFile()
254 : QFileDevice(*new QFilePrivate, 0)
255{
256}
257/*!
258 Constructs a new file object with the given \a parent.
259*/
260QFile::QFile(QObject *parent)
261 : QFileDevice(*new QFilePrivate, parent)
262{
263}
264/*!
265 Constructs a new file object to represent the file with the given \a name.
266*/
267QFile::QFile(const QString &name)
268 : QFileDevice(*new QFilePrivate, 0)
269{
270 Q_D(QFile);
271 d->fileName = name;
272}
273/*!
274 Constructs a new file object with the given \a parent to represent the
275 file with the specified \a name.
276*/
277QFile::QFile(const QString &name, QObject *parent)
278 : QFileDevice(*new QFilePrivate, parent)
279{
280 Q_D(QFile);
281 d->fileName = name;
282}
283/*!
284 \internal
285*/
286QFile::QFile(QFilePrivate &dd, QObject *parent)
287 : QFileDevice(dd, parent)
288{
289}
290#endif
291
292/*!
293 Destroys the file object, closing it if necessary.
294*/
295QFile::~QFile()
296{
297}
298
299/*!
300 Returns the name set by setFileName() or to the QFile
301 constructors.
302
303 \sa setFileName(), QFileInfo::fileName()
304*/
305QString QFile::fileName() const
306{
307 Q_D(const QFile);
308 return d->engine()->fileName(QAbstractFileEngine::DefaultName);
309}
310
311/*!
312 Sets the \a name of the file. The name can have no path, a
313 relative path, or an absolute path.
314
315 Do not call this function if the file has already been opened.
316
317 If the file name has no path or a relative path, the path used
318 will be the application's current directory path
319 \e{at the time of the open()} call.
320
321 Example:
322 \snippet code/src_corelib_io_qfile.cpp 0
323
324 Note that the directory separator "/" works for all operating
325 systems supported by Qt.
326
327 \sa fileName(), QFileInfo, QDir
328*/
329void
330QFile::setFileName(const QString &name)
331{
332 Q_D(QFile);
333 if (isOpen()) {
334 file_already_open(*this, "setFileName");
335 close();
336 }
337 d->fileEngine.reset(); //get a new file engine later
338 d->fileName = name;
339}
340
341/*!
342 \fn QString QFile::decodeName(const char *localFileName)
343
344 \overload
345
346 Returns the Unicode version of the given \a localFileName. See
347 encodeName() for details.
348*/
349
350/*!
351 \fn QByteArray QFile::encodeName(const QString &fileName)
352
353 Converts \a fileName to the local 8-bit
354 encoding determined by the user's locale. This is sufficient for
355 file names that the user chooses. File names hard-coded into the
356 application should only use 7-bit ASCII filename characters.
357
358 \sa decodeName()
359*/
360
361/*!
362 \typedef QFile::EncoderFn
363 \obsolete
364
365 This is a typedef for a pointer to a function with the following
366 signature:
367
368 \snippet code/src_corelib_io_qfile.cpp 1
369
370 \sa setEncodingFunction(), encodeName()
371*/
372
373/*!
374 \fn QString QFile::decodeName(const QByteArray &localFileName)
375
376 This does the reverse of QFile::encodeName() using \a localFileName.
377
378 \sa encodeName()
379*/
380
381/*!
382 \fn void QFile::setEncodingFunction(EncoderFn function)
383 \obsolete
384
385 This function does nothing. It is provided for compatibility with Qt 4 code
386 that attempted to set a different encoding function for file names. That
387 feature is flawed and no longer supported in Qt 5.
388
389 \sa encodeName(), setDecodingFunction()
390*/
391
392/*!
393 \typedef QFile::DecoderFn
394
395 This is a typedef for a pointer to a function with the following
396 signature:
397
398 \snippet code/src_corelib_io_qfile.cpp 2
399
400 \sa setDecodingFunction()
401*/
402
403/*!
404 \fn void QFile::setDecodingFunction(DecoderFn function)
405 \obsolete
406
407 This function does nothing. It is provided for compatibility with Qt 4 code
408 that attempted to set a different decoding function for file names. That
409 feature is flawed and no longer supported in Qt 5.
410
411 \sa setEncodingFunction(), decodeName()
412*/
413
414/*!
415 \overload
416
417 Returns \c true if the file specified by fileName() exists; otherwise
418 returns \c false.
419
420 \sa fileName(), setFileName()
421*/
422
423bool
424QFile::exists() const
425{
426 Q_D(const QFile);
427 // 0x1000000 = QAbstractFileEngine::Refresh, forcing an update
428 return (d->engine()->fileFlags(QAbstractFileEngine::FlagsMask
429 | QAbstractFileEngine::Refresh) & QAbstractFileEngine::ExistsFlag);
430}
431
432/*!
433 Returns \c true if the file specified by \a fileName exists; otherwise
434 returns \c false.
435
436 \note If \a fileName is a symlink that points to a non-existing
437 file, false is returned.
438*/
439
440bool
441QFile::exists(const QString &fileName)
442{
443 return QFileInfo::exists(fileName);
444}
445
446/*!
447 \fn QString QFile::symLinkTarget() const
448 \since 4.2
449 \overload
450
451 Returns the absolute path of the file or directory a symlink (or shortcut
452 on Windows) points to, or a an empty string if the object isn't a symbolic
453 link.
454
455 This name may not represent an existing file; it is only a string.
456 QFile::exists() returns \c true if the symlink points to an existing file.
457
458 \sa fileName(), setFileName()
459*/
460QString QFile::symLinkTarget() const
461{
462 Q_D(const QFile);
463 return d->engine()->fileName(QAbstractFileEngine::LinkName);
464}
465
466#if QT_DEPRECATED_SINCE(5, 13)
467/*!
468 \obsolete
469
470 Use symLinkTarget() instead.
471*/
472QString
473QFile::readLink() const
474{
475 return symLinkTarget();
476}
477#endif
478
479/*!
480 \fn static QString QFile::symLinkTarget(const QString &fileName)
481 \since 4.2
482
483 Returns the absolute path of the file or directory referred to by the
484 symlink (or shortcut on Windows) specified by \a fileName, or returns an
485 empty string if the \a fileName does not correspond to a symbolic link.
486
487 This name may not represent an existing file; it is only a string.
488 QFile::exists() returns \c true if the symlink points to an existing file.
489*/
490QString QFile::symLinkTarget(const QString &fileName)
491{
492 return QFileInfo(fileName).symLinkTarget();
493}
494
495#if QT_DEPRECATED_SINCE(5, 13)
496/*!
497 \obsolete
498
499 Use symLinkTarget() instead.
500*/
501QString
502QFile::readLink(const QString &fileName)
503{
504 return symLinkTarget(fileName);
505}
506#endif
507
508/*!
509 Removes the file specified by fileName(). Returns \c true if successful;
510 otherwise returns \c false.
511
512 The file is closed before it is removed.
513
514 \sa setFileName()
515*/
516
517bool
518QFile::remove()
519{
520 Q_D(QFile);
521 if (d->fileName.isEmpty() &&
522 !static_cast<QFSFileEngine *>(d->engine())->isUnnamedFile()) {
523 qWarning("QFile::remove: Empty or null file name");
524 return false;
525 }
526 unsetError();
527 close();
528 if(error() == QFile::NoError) {
529 if (d->engine()->remove()) {
530 unsetError();
531 return true;
532 }
533 d->setError(QFile::RemoveError, d->fileEngine->errorString());
534 }
535 return false;
536}
537
538/*!
539 \overload
540
541 Removes the file specified by the \a fileName given.
542
543 Returns \c true if successful; otherwise returns \c false.
544
545 \sa remove()
546*/
547
548bool
549QFile::remove(const QString &fileName)
550{
551 return QFile(fileName).remove();
552}
553
554/*!
555 Renames the file currently specified by fileName() to \a newName.
556 Returns \c true if successful; otherwise returns \c false.
557
558 If a file with the name \a newName already exists, rename() returns \c false
559 (i.e., QFile will not overwrite it).
560
561 The file is closed before it is renamed.
562
563 If the rename operation fails, Qt will attempt to copy this file's
564 contents to \a newName, and then remove this file, keeping only
565 \a newName. If that copy operation fails or this file can't be removed,
566 the destination file \a newName is removed to restore the old state.
567
568 \sa setFileName()
569*/
570
571bool
572QFile::rename(const QString &newName)
573{
574 Q_D(QFile);
575
576 // if this is a QTemporaryFile, the virtual fileName() call here may do something
577 if (fileName().isEmpty()) {
578 qWarning("QFile::rename: Empty or null file name");
579 return false;
580 }
581 if (d->fileName == newName) {
582 d->setError(QFile::RenameError, tr("Destination file is the same file."));
583 return false;
584 }
585 if (!exists()) {
586 d->setError(QFile::RenameError, tr("Source file does not exist."));
587 return false;
588 }
589
590 // If the file exists and it is a case-changing rename ("foo" -> "Foo"),
591 // compare Ids to make sure it really is a different file.
592 // Note: this does not take file engines into account.
593 bool changingCase = false;
594 QByteArray targetId = QFileSystemEngine::id(QFileSystemEntry(newName));
595 if (!targetId.isNull()) {
596 QByteArray fileId = d->fileEngine ?
597 d->fileEngine->id() :
598 QFileSystemEngine::id(QFileSystemEntry(d->fileName));
599 changingCase = (fileId == targetId && d->fileName.compare(newName, Qt::CaseInsensitive) == 0);
600 if (!changingCase) {
601 d->setError(QFile::RenameError, tr("Destination file exists"));
602 return false;
603 }
604
605#ifdef Q_OS_LINUX
606 // rename() on Linux simply does nothing when renaming "foo" to "Foo" on a case-insensitive
607 // FS, such as FAT32. Move the file away and rename in 2 steps to work around.
608 QTemporaryFileName tfn(d->fileName);
609 QFileSystemEntry src(d->fileName);
610 QSystemError error;
611 for (int attempt = 0; attempt < 16; ++attempt) {
612 QFileSystemEntry tmp(tfn.generateNext(), QFileSystemEntry::FromNativePath());
613
614 // rename to temporary name
615 if (!QFileSystemEngine::renameFile(src, tmp, error))
616 continue;
617
618 // rename to final name
619 if (QFileSystemEngine::renameFile(tmp, QFileSystemEntry(newName), error)) {
620 d->fileEngine->setFileName(newName);
621 d->fileName = newName;
622 return true;
623 }
624
625 // We need to restore the original file.
626 QSystemError error2;
627 if (QFileSystemEngine::renameFile(tmp, src, error2))
628 break; // report the original error, below
629
630 // report both errors
631 d->setError(QFile::RenameError,
632 tr("Error while renaming: %1").arg(error.toString())
633 + QLatin1Char('\n')
634 + tr("Unable to restore from %1: %2").
635 arg(QDir::toNativeSeparators(tmp.filePath()), error2.toString()));
636 return false;
637 }
638 d->setError(QFile::RenameError,
639 tr("Error while renaming: %1").arg(error.toString()));
640 return false;
641#endif // Q_OS_LINUX
642 }
643 unsetError();
644 close();
645 if(error() == QFile::NoError) {
646 if (changingCase ? d->engine()->renameOverwrite(newName) : d->engine()->rename(newName)) {
647 unsetError();
648 // engine was able to handle the new name so we just reset it
649 d->fileEngine->setFileName(newName);
650 d->fileName = newName;
651 return true;
652 }
653
654 if (isSequential()) {
655 d->setError(QFile::RenameError, tr("Will not rename sequential file using block copy"));
656 return false;
657 }
658
659 QFile out(newName);
660 if (open(QIODevice::ReadOnly)) {
661 if (out.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
662 bool error = false;
663 char block[4096];
664 qint64 bytes;
665 while ((bytes = read(block, sizeof(block))) > 0) {
666 if (bytes != out.write(block, bytes)) {
667 d->setError(QFile::RenameError, out.errorString());
668 error = true;
669 break;
670 }
671 }
672 if (bytes == -1) {
673 d->setError(QFile::RenameError, errorString());
674 error = true;
675 }
676 if(!error) {
677 if (!remove()) {
678 d->setError(QFile::RenameError, tr("Cannot remove source file"));
679 error = true;
680 }
681 }
682 if (error) {
683 out.remove();
684 } else {
685 d->fileEngine->setFileName(newName);
686 setPermissions(permissions());
687 unsetError();
688 setFileName(newName);
689 }
690 close();
691 return !error;
692 }
693 close();
694 d->setError(QFile::RenameError,
695 tr("Cannot open destination file: %1").arg(out.errorString()));
696 } else {
697 d->setError(QFile::RenameError, errorString());
698 }
699 }
700 return false;
701}
702
703/*!
704 \overload
705
706 Renames the file \a oldName to \a newName. Returns \c true if
707 successful; otherwise returns \c false.
708
709 If a file with the name \a newName already exists, rename() returns \c false
710 (i.e., QFile will not overwrite it).
711
712 \sa rename()
713*/
714
715bool
716QFile::rename(const QString &oldName, const QString &newName)
717{
718 return QFile(oldName).rename(newName);
719}
720
721/*!
722
723 Creates a link named \a linkName that points to the file currently specified by
724 fileName(). What a link is depends on the underlying filesystem (be it a
725 shortcut on Windows or a symbolic link on Unix). Returns \c true if successful;
726 otherwise returns \c false.
727
728 This function will not overwrite an already existing entity in the file system;
729 in this case, \c link() will return false and set \l{QFile::}{error()} to
730 return \l{QFile::}{RenameError}.
731
732 \note To create a valid link on Windows, \a linkName must have a \c{.lnk} file extension.
733
734 \sa setFileName()
735*/
736
737bool
738QFile::link(const QString &linkName)
739{
740 Q_D(QFile);
741 if (fileName().isEmpty()) {
742 qWarning("QFile::link: Empty or null file name");
743 return false;
744 }
745 QFileInfo fi(linkName);
746 if (d->engine()->link(fi.absoluteFilePath())) {
747 unsetError();
748 return true;
749 }
750 d->setError(QFile::RenameError, d->fileEngine->errorString());
751 return false;
752}
753
754/*!
755 \overload
756
757 Creates a link named \a linkName that points to the file \a fileName. What a link is
758 depends on the underlying filesystem (be it a shortcut on Windows
759 or a symbolic link on Unix). Returns \c true if successful; otherwise
760 returns \c false.
761
762 \sa link()
763*/
764
765bool
766QFile::link(const QString &fileName, const QString &linkName)
767{
768 return QFile(fileName).link(linkName);
769}
770
771/*!
772 Copies the file currently specified by fileName() to a file called
773 \a newName. Returns \c true if successful; otherwise returns \c false.
774
775 Note that if a file with the name \a newName already exists,
776 copy() returns \c false (i.e. QFile will not overwrite it).
777
778 The source file is closed before it is copied.
779
780 \sa setFileName()
781*/
782
783bool
784QFile::copy(const QString &newName)
785{
786 Q_D(QFile);
787 if (fileName().isEmpty()) {
788 qWarning("QFile::copy: Empty or null file name");
789 return false;
790 }
791 if (QFile::exists(newName)) {
792 // ### Race condition. If a file is moved in after this, it /will/ be
793 // overwritten. On Unix, the proper solution is to use hardlinks:
794 // return ::link(old, new) && ::remove(old); See also rename().
795 d->setError(QFile::CopyError, tr("Destination file exists"));
796 return false;
797 }
798 unsetError();
799 close();
800 if(error() == QFile::NoError) {
801 if (d->engine()->copy(newName)) {
802 unsetError();
803 return true;
804 } else {
805 bool error = false;
806 if(!open(QFile::ReadOnly)) {
807 error = true;
808 d->setError(QFile::CopyError, tr("Cannot open %1 for input").arg(d->fileName));
809 } else {
810 const auto fileTemplate = QLatin1String("%1/qt_temp.XXXXXX");
811#ifdef QT_NO_TEMPORARYFILE
812 QFile out(fileTemplate.arg(QFileInfo(newName).path()));
813 if (!out.open(QIODevice::ReadWrite))
814 error = true;
815#else
816 QTemporaryFile out(fileTemplate.arg(QFileInfo(newName).path()));
817 if (!out.open()) {
818 out.setFileTemplate(fileTemplate.arg(QDir::tempPath()));
819 if (!out.open())
820 error = true;
821 }
822#endif
823 if (error) {
824 out.close();
825 close();
826 d->setError(QFile::CopyError, tr("Cannot open for output: %1").arg(out.errorString()));
827 } else {
828 if (!d->engine()->cloneTo(out.d_func()->engine())) {
829 char block[4096];
830 qint64 totalRead = 0;
831 while (!atEnd()) {
832 qint64 in = read(block, sizeof(block));
833 if (in <= 0)
834 break;
835 totalRead += in;
836 if (in != out.write(block, in)) {
837 close();
838 d->setError(QFile::CopyError, tr("Failure to write block"));
839 error = true;
840 break;
841 }
842 }
843
844 if (totalRead != size()) {
845 // Unable to read from the source. The error string is
846 // already set from read().
847 error = true;
848 }
849 }
850
851 if (!error) {
852 // Sync to disk if possible. Ignore errors (e.g. not supported).
853 d->fileEngine->syncToDisk();
854
855 if (!out.rename(newName)) {
856 error = true;
857 close();
858 d->setError(QFile::CopyError, tr("Cannot create %1 for output").arg(newName));
859 }
860 }
861#ifdef QT_NO_TEMPORARYFILE
862 if (error)
863 out.remove();
864#else
865 if (!error)
866 out.setAutoRemove(false);
867#endif
868 }
869 }
870 if(!error) {
871 QFile::setPermissions(newName, permissions());
872 close();
873 unsetError();
874 return true;
875 }
876 }
877 }
878 return false;
879}
880
881/*!
882 \overload
883
884 Copies the file \a fileName to \a newName. Returns \c true if successful;
885 otherwise returns \c false.
886
887 If a file with the name \a newName already exists, copy() returns \c false
888 (i.e., QFile will not overwrite it).
889
890 \sa rename()
891*/
892
893bool
894QFile::copy(const QString &fileName, const QString &newName)
895{
896 return QFile(fileName).copy(newName);
897}
898
899/*!
900 Opens the file using OpenMode \a mode, returning true if successful;
901 otherwise false.
902
903 The \a mode must be QIODevice::ReadOnly, QIODevice::WriteOnly, or
904 QIODevice::ReadWrite. It may also have additional flags, such as
905 QIODevice::Text and QIODevice::Unbuffered.
906
907 \note In \l{QIODevice::}{WriteOnly} or \l{QIODevice::}{ReadWrite}
908 mode, if the relevant file does not already exist, this function
909 will try to create a new file before opening it.
910
911 \sa QIODevice::OpenMode, setFileName()
912*/
913bool QFile::open(OpenMode mode)
914{
915 Q_D(QFile);
916 if (isOpen())
917 return file_already_open(*this);
918 // Either Append or NewOnly implies WriteOnly
919 if (mode & (Append | NewOnly))
920 mode |= WriteOnly;
921 unsetError();
922 if ((mode & (ReadOnly | WriteOnly)) == 0) {
923 qWarning("QIODevice::open: File access not specified");
924 return false;
925 }
926
927 // QIODevice provides the buffering, so there's no need to request it from the file engine.
928 if (d->engine()->open(mode | QIODevice::Unbuffered)) {
929 QIODevice::open(mode);
930 if (mode & Append)
931 seek(size());
932 return true;
933 }
934 QFile::FileError err = d->fileEngine->error();
935 if(err == QFile::UnspecifiedError)
936 err = QFile::OpenError;
937 d->setError(err, d->fileEngine->errorString());
938 return false;
939}
940
941/*!
942 \overload
943
944 Opens the existing file handle \a fh in the given \a mode.
945 \a handleFlags may be used to specify additional options.
946 Returns \c true if successful; otherwise returns \c false.
947
948 Example:
949 \snippet code/src_corelib_io_qfile.cpp 3
950
951 When a QFile is opened using this function, behaviour of close() is
952 controlled by the AutoCloseHandle flag.
953 If AutoCloseHandle is specified, and this function succeeds,
954 then calling close() closes the adopted handle.
955 Otherwise, close() does not actually close the file, but only flushes it.
956
957 \b{Warning:}
958 \list 1
959 \li If \a fh does not refer to a regular file, e.g., it is \c stdin,
960 \c stdout, or \c stderr, you may not be able to seek(). size()
961 returns \c 0 in those cases. See QIODevice::isSequential() for
962 more information.
963 \li Since this function opens the file without specifying the file name,
964 you cannot use this QFile with a QFileInfo.
965 \endlist
966
967 \sa close()
968
969 \b{Note for the Windows Platform}
970
971 \a fh must be opened in binary mode (i.e., the mode string must contain
972 'b', as in "rb" or "wb") when accessing files and other random-access
973 devices. Qt will translate the end-of-line characters if you pass
974 QIODevice::Text to \a mode. Sequential devices, such as stdin and stdout,
975 are unaffected by this limitation.
976
977 You need to enable support for console applications in order to use the
978 stdin, stdout and stderr streams at the console. To do this, add the
979 following declaration to your application's project file:
980
981 \snippet code/src_corelib_io_qfile.cpp 4
982*/
983bool QFile::open(FILE *fh, OpenMode mode, FileHandleFlags handleFlags)
984{
985 Q_D(QFile);
986 if (isOpen())
987 return file_already_open(*this);
988 // Either Append or NewOnly implies WriteOnly
989 if (mode & (Append | NewOnly))
990 mode |= WriteOnly;
991 unsetError();
992 if ((mode & (ReadOnly | WriteOnly)) == 0) {
993 qWarning("QFile::open: File access not specified");
994 return false;
995 }
996
997 // QIODevice provides the buffering, so request unbuffered file engines
998 if (d->openExternalFile(mode | Unbuffered, fh, handleFlags)) {
999 QIODevice::open(mode);
1000 if (!(mode & Append) && !isSequential()) {
1001 qint64 pos = (qint64)QT_FTELL(fh);
1002 if (pos != -1) {
1003 // Skip redundant checks in QFileDevice::seek().
1004 QIODevice::seek(pos);
1005 }
1006 }
1007 return true;
1008 }
1009 return false;
1010}
1011
1012/*!
1013 \overload
1014
1015 Opens the existing file descriptor \a fd in the given \a mode.
1016 \a handleFlags may be used to specify additional options.
1017 Returns \c true if successful; otherwise returns \c false.
1018
1019 When a QFile is opened using this function, behaviour of close() is
1020 controlled by the AutoCloseHandle flag.
1021 If AutoCloseHandle is specified, and this function succeeds,
1022 then calling close() closes the adopted handle.
1023 Otherwise, close() does not actually close the file, but only flushes it.
1024
1025 The QFile that is opened using this function is automatically set
1026 to be in raw mode; this means that the file input/output functions
1027 are slow. If you run into performance issues, you should try to
1028 use one of the other open functions.
1029
1030 \warning If \a fd is not a regular file, e.g, it is 0 (\c stdin),
1031 1 (\c stdout), or 2 (\c stderr), you may not be able to seek(). In
1032 those cases, size() returns \c 0. See QIODevice::isSequential()
1033 for more information.
1034
1035 \warning Since this function opens the file without specifying the file name,
1036 you cannot use this QFile with a QFileInfo.
1037
1038 \sa close()
1039*/
1040bool QFile::open(int fd, OpenMode mode, FileHandleFlags handleFlags)
1041{
1042 Q_D(QFile);
1043 if (isOpen())
1044 return file_already_open(*this);
1045 // Either Append or NewOnly implies WriteOnly
1046 if (mode & (Append | NewOnly))
1047 mode |= WriteOnly;
1048 unsetError();
1049 if ((mode & (ReadOnly | WriteOnly)) == 0) {
1050 qWarning("QFile::open: File access not specified");
1051 return false;
1052 }
1053
1054 // QIODevice provides the buffering, so request unbuffered file engines
1055 if (d->openExternalFile(mode | Unbuffered, fd, handleFlags)) {
1056 QIODevice::open(mode);
1057 if (!(mode & Append) && !isSequential()) {
1058 qint64 pos = (qint64)QT_LSEEK(fd, QT_OFF_T(0), SEEK_CUR);
1059 if (pos != -1) {
1060 // Skip redundant checks in QFileDevice::seek().
1061 QIODevice::seek(pos);
1062 }
1063 }
1064 return true;
1065 }
1066 return false;
1067}
1068
1069/*!
1070 \reimp
1071*/
1072bool QFile::resize(qint64 sz)
1073{
1074 return QFileDevice::resize(sz); // for now
1075}
1076
1077/*!
1078 \overload
1079
1080 Sets \a fileName to size (in bytes) \a sz. Returns \c true if
1081 the resize succeeds; false otherwise. If \a sz is larger than \a
1082 fileName currently is the new bytes will be set to 0, if \a sz is
1083 smaller the file is simply truncated.
1084
1085 \warning This function can fail if the file doesn't exist.
1086
1087 \sa resize()
1088*/
1089
1090bool
1091QFile::resize(const QString &fileName, qint64 sz)
1092{
1093 return QFile(fileName).resize(sz);
1094}
1095
1096/*!
1097 \reimp
1098*/
1099QFile::Permissions QFile::permissions() const
1100{
1101 return QFileDevice::permissions(); // for now
1102}
1103
1104/*!
1105 \overload
1106
1107 Returns the complete OR-ed together combination of
1108 QFile::Permission for \a fileName.
1109*/
1110
1111QFile::Permissions
1112QFile::permissions(const QString &fileName)
1113{
1114 return QFile(fileName).permissions();
1115}
1116
1117/*!
1118 Sets the permissions for the file to the \a permissions specified.
1119 Returns \c true if successful, or \c false if the permissions cannot be
1120 modified.
1121
1122 \warning This function does not manipulate ACLs, which may limit its
1123 effectiveness.
1124
1125 \sa permissions(), setFileName()
1126*/
1127
1128bool QFile::setPermissions(Permissions permissions)
1129{
1130 return QFileDevice::setPermissions(permissions); // for now
1131}
1132
1133/*!
1134 \overload
1135
1136 Sets the permissions for \a fileName file to \a permissions.
1137*/
1138
1139bool
1140QFile::setPermissions(const QString &fileName, Permissions permissions)
1141{
1142 return QFile(fileName).setPermissions(permissions);
1143}
1144
1145/*!
1146 \reimp
1147*/
1148qint64 QFile::size() const
1149{
1150 return QFileDevice::size(); // for now
1151}
1152
1153QT_END_NAMESPACE
1154
1155#ifndef QT_NO_QOBJECT
1156#include "moc_qfile.cpp"
1157#endif
1158