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