1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include <QtTest/QtTest>
43 #include <qplatformdefs.h>
45 #include <QCoreApplication>
51 #include <private/qabstractfileengine_p.h>
52 #include <private/qfsfileengine_p.h>
56 extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;
60 #if !defined(Q_OS_WINCE)
65 # include <qt_windows.h>
67 # include <sys/types.h>
71 # include <sys/mount.h>
72 #elif defined(Q_OS_LINUX)
74 #elif defined(Q_OS_FREEBSD)
75 # include <sys/param.h>
76 # include <sys/mount.h>
77 #elif defined(Q_OS_IRIX)
78 # include <sys/statfs.h>
79 #elif defined(Q_OS_WINCE)
80 # include <qplatformdefs.h>
86 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
87 #include "../../../network-settings.h"
91 #define STDIN_FILENO 0
95 #define STDOUT_FILENO 1
99 #define STDERR_FILENO 2
102 #ifndef QT_OPEN_BINARY
103 #define QT_OPEN_BINARY 0
106 Q_DECLARE_METATYPE(QFile::FileError)
108 class tst_QFile : public QObject
116 void cleanupTestCase();
120 void openUnbuffered();
130 void readLineNullInLine();
133 void readAllBuffer();
135 void readLineStdin();
136 void readLineStdin_lineByLine();
138 void missingEndOfLine();
144 void permissions_data();
146 void permissionsNtfs_data();
147 void permissionsNtfs();
148 void setPermissions();
150 void copyAfterFail();
151 void copyRemovesTemporaryFile() const;
152 void copyShouldntOverwrite();
156 void absolutePathLinkToRelativePath();
157 void readBrokenLink();
158 void readTextFile_data();
160 void readTextFile2();
161 void writeTextFile_data();
162 void writeTextFile();
163 /* void largeFileSupport(); */
164 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
165 void largeUncFileSupport();
174 void seekAfterEndOfFile();
175 void FILEReadWrite();
176 void i18nFileName_data();
178 void longFileName_data();
180 void fileEngineHandler();
181 void useQFileInAFileHandler();
183 void remove_and_exists();
184 void removeOpenFile();
186 void writeLargeDataBlock_data();
187 void writeLargeDataBlock();
188 void readFromWriteOnlyFile();
189 void writeToReadOnlyFile();
194 void renameWithAtEndSpecialFile() const;
195 void renameFallback();
196 void renameMultiple();
197 void appendAndRead();
198 void miscWithUncPathAsCurrentDir();
199 void standarderror();
201 void nativeHandleLeaks();
208 void mapResource_data();
210 void mapOpenMode_data();
213 void openStandardStreamsFileDescriptors();
214 void openStandardStreamsBufferedStreams();
219 void objectConstructors();
221 void caseSensitivity();
223 void autocloseHandle();
225 void posAfterFailedStat();
227 void openDirectory();
231 // disabled this test for the moment... it hangs
232 void invalidFile_data();
243 bool openFd(QFile &file, QIODevice::OpenMode mode, QFile::FileHandleFlags handleFlags)
245 int fdMode = QT_OPEN_LARGEFILE | QT_OPEN_BINARY;
247 // File will be truncated if in Write mode.
248 if (mode & QIODevice::WriteOnly)
249 fdMode |= QT_OPEN_WRONLY | QT_OPEN_TRUNC;
250 if (mode & QIODevice::ReadOnly)
251 fdMode |= QT_OPEN_RDONLY;
253 fd_ = QT_OPEN(qPrintable(file.fileName()), fdMode);
255 return (-1 != fd_) && file.open(fd_, mode, handleFlags);
258 bool openStream(QFile &file, QIODevice::OpenMode mode, QFile::FileHandleFlags handleFlags)
260 char const *streamMode = "";
262 // File will be truncated if in Write mode.
263 if (mode & QIODevice::WriteOnly)
265 else if (mode & QIODevice::ReadOnly)
268 stream_ = QT_FOPEN(qPrintable(file.fileName()), streamMode);
270 return stream_ && file.open(stream_, mode, handleFlags);
273 bool openFile(QFile &file, QIODevice::OpenMode mode, FileType type = OpenQFile, QFile::FileHandleFlags handleFlags = QFile::DontCloseHandle)
275 if (mode & QIODevice::WriteOnly && !file.exists())
277 // Make sure the file exists
278 QFile createFile(file.fileName());
279 if (!createFile.open(QIODevice::ReadWrite))
283 // Note: openFd and openStream will truncate the file if write mode.
287 return file.open(mode);
290 return openFd(file, mode, handleFlags);
293 return openStream(file, mode, handleFlags);
295 case NumberOfFileTypes:
302 void closeFile(QFile &file)
319 void tst_QFile::init()
325 void tst_QFile::cleanup()
327 // for copyFallback()
328 if (QFile::exists("file-copy-destination.txt")) {
329 QFile::setPermissions("file-copy-destination.txt",
330 QFile::ReadOwner | QFile::WriteOwner);
331 QFile::remove("file-copy-destination.txt");
334 // for renameFallback()
335 QFile::remove("file-rename-destination.txt");
337 // for copyAfterFail()
338 QFile::remove("file-to-be-copied.txt");
339 QFile::remove("existing-file.txt");
340 QFile::remove("copied-file-1.txt");
341 QFile::remove("copied-file-2.txt");
343 // for renameMultiple()
344 QFile::remove("file-to-be-renamed.txt");
345 QFile::remove("existing-file.txt");
346 QFile::remove("file-renamed-once.txt");
347 QFile::remove("file-renamed-twice.txt");
355 void tst_QFile::initTestCase()
357 QString workingDir = QFileInfo(QFINDTESTDATA("stdinprocess")).absolutePath();
358 QVERIFY2(!workingDir.isEmpty(), qPrintable("Could not find working directory!"));
359 QVERIFY2(QDir::setCurrent(workingDir), qPrintable("Could not chdir to " + workingDir));
361 QFile::remove("noreadfile");
363 // create a file and make it read-only
364 QFile file("readonlyfile");
365 file.open(QFile::WriteOnly);
368 file.setPermissions(QFile::ReadOwner);
370 // create another file and make it not readable
371 file.setFileName("noreadfile");
372 file.open(QFile::WriteOnly);
375 file.setPermissions(0);
378 void tst_QFile::cleanupTestCase()
380 // clean up the files we created
381 QFile::remove("readonlyfile");
382 QFile::remove("noreadfile");
383 QFile::remove("myLink.lnk");
384 QFile::remove("appendme.txt");
385 QFile::remove("createme.txt");
386 QFile::remove("file.txt");
387 QFile::remove("genfile.txt");
388 QFile::remove("seekToPos.txt");
389 QFile::remove("setsizeseek.txt");
390 QFile::remove("stdfile.txt");
391 QFile::remove("textfile.txt");
392 QFile::remove("truncate.txt");
393 QFile::remove("winfile.txt");
394 QFile::remove("writeonlyfile");
395 QFile::remove("largeblockfile.txt");
396 QFile::remove("tst_qfile_copy.cpp");
397 QFile::remove("nullinline.txt");
398 QFile::remove("myLink2.lnk");
399 QFile::remove("resources");
400 QFile::remove("qfile_map_testfile");
401 QFile::remove("readAllBuffer.txt");
402 QFile::remove("qt_file.tmp");
403 QFile::remove("File.txt");
406 //------------------------------------------
407 // The 'testfile' is currently just a
408 // testfile. The path of this file, the
409 // attributes and the contents itself
410 // will be changed as far as we have a
411 // proper way to handle files in the
412 // testing environment.
413 //------------------------------------------
415 void tst_QFile::exists()
417 QFile f( QFINDTESTDATA("testfile.txt") );
420 QFile file("nobodyhassuchafile");
422 QVERIFY(!file.exists());
424 QFile file2("nobodyhassuchafile");
425 QVERIFY(file2.open(QIODevice::WriteOnly));
428 QVERIFY(file.exists());
430 QVERIFY(file.open(QIODevice::WriteOnly));
432 QVERIFY(file.exists());
435 QVERIFY(!file.exists());
437 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
438 QFile unc("//" + QtNetworkSettings::winServerName() + "/testshare/readme.txt");
439 QVERIFY(unc.exists());
443 void tst_QFile::open_data()
445 QTest::addColumn<QString>("filename");
446 QTest::addColumn<int>("mode");
447 QTest::addColumn<bool>("ok");
448 QTest::addColumn<QFile::FileError>("status");
451 static const QString denied("Operation not permitted");
453 static const QString denied("Permission denied");
455 QTest::newRow( "exist_readOnly" )
456 << QString(QFINDTESTDATA("testfile.txt")) << int(QIODevice::ReadOnly)
457 << true << QFile::NoError;
459 QTest::newRow( "exist_writeOnly" )
460 << QString("readonlyfile")
461 << int(QIODevice::WriteOnly)
465 QTest::newRow( "exist_append" )
466 << QString("readonlyfile") << int(QIODevice::Append)
467 << false << QFile::OpenError;
469 QTest::newRow( "nonexist_readOnly" )
470 << QString("nonExist.txt") << int(QIODevice::ReadOnly)
471 << false << QFile::OpenError;
473 QTest::newRow("emptyfile")
475 << int(QIODevice::ReadOnly)
479 QTest::newRow("nullfile") << QString() << int(QIODevice::ReadOnly) << false
482 QTest::newRow("two-dots") << QString(QFINDTESTDATA("two.dots.file")) << int(QIODevice::ReadOnly) << true
485 QTest::newRow("readonlyfile") << QString("readonlyfile") << int(QIODevice::WriteOnly)
486 << false << QFile::OpenError;
487 QTest::newRow("noreadfile") << QString("noreadfile") << int(QIODevice::ReadOnly)
488 << false << QFile::OpenError;
489 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
490 //opening devices requires administrative privileges (and elevation).
491 HANDLE hTest = CreateFile(_T("\\\\.\\PhysicalDrive0"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
492 if (hTest != INVALID_HANDLE_VALUE) {
494 QTest::newRow("//./PhysicalDrive0") << QString("//./PhysicalDrive0") << int(QIODevice::ReadOnly)
495 << true << QFile::NoError;
497 QTest::newRow("//./PhysicalDrive0") << QString("//./PhysicalDrive0") << int(QIODevice::ReadOnly)
498 << false << QFile::OpenError;
500 QTest::newRow("uncFile") << "//" + QtNetworkSettings::winServerName() + "/testshare/test.pri" << int(QIODevice::ReadOnly)
501 << true << QFile::NoError;
505 void tst_QFile::open()
507 QFETCH( QString, filename );
514 #if defined(Q_OS_UNIX)
516 // root and Chuck Norris don't care for file permissions. Skip.
517 QSKIP("Running this test as root doesn't make sense");
520 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
521 QEXPECT_FAIL("noreadfile", "Windows does not currently support non-readable files.", Abort);
523 if (filename.isEmpty())
524 QTest::ignoreMessage(QtWarningMsg, "QFSFileEngine::open: No file name specified");
526 QCOMPARE(f.open( QIODevice::OpenMode(mode) ), ok);
528 QTEST( f.error(), "status" );
531 void tst_QFile::openUnbuffered()
533 QFile file(QFINDTESTDATA("testfile.txt"));
534 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Unbuffered));
536 QVERIFY(file.seek(1));
537 QCOMPARE(file.pos(), qint64(1));
538 QVERIFY(file.getChar(&c));
539 QCOMPARE(file.pos(), qint64(2));
541 QVERIFY(file.seek(3));
542 QCOMPARE(file.pos(), qint64(3));
543 QVERIFY(file.getChar(&d));
544 QCOMPARE(file.pos(), qint64(4));
545 QVERIFY(file.seek(1));
546 QCOMPARE(file.pos(), qint64(1));
548 QVERIFY(file.getChar(&c2));
549 QCOMPARE(file.pos(), qint64(2));
550 QVERIFY(file.seek(3));
551 QCOMPARE(file.pos(), qint64(3));
553 QVERIFY(file.getChar(&d2));
554 QCOMPARE(file.pos(), qint64(4));
561 void tst_QFile::size_data()
563 QTest::addColumn<QString>("filename");
564 QTest::addColumn<qint64>("size");
566 QTest::newRow( "exist01" ) << QString(QFINDTESTDATA("testfile.txt")) << (qint64)245;
567 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
568 // Only test UNC on Windows./
569 QTest::newRow("unc") << "//" + QString(QtNetworkSettings::winServerName() + "/testshare/test.pri") << (qint64)34;
573 void tst_QFile::size()
575 QFETCH( QString, filename );
576 QFETCH( qint64, size );
579 filename = QFileInfo(filename).absoluteFilePath();
584 QCOMPARE( f.size(), size );
586 QVERIFY( f.open(QIODevice::ReadOnly) );
587 QCOMPARE( f.size(), size );
592 FILE* stream = QT_FOPEN(filename.toLocal8Bit().constData(), "rb");
594 QVERIFY( f.open(stream, QIODevice::ReadOnly) );
595 QCOMPARE( f.size(), size );
601 // Currently low level file I/O is not well supported on Windows CE, so
602 // skip this part of the test.
607 int fd = QT_OPEN(filename.toLocal8Bit().constData(), QT_OPEN_RDONLY);
610 QVERIFY( f.open(fd, QIODevice::ReadOnly) );
611 QCOMPARE( f.size(), size );
619 void tst_QFile::sizeNoExist()
621 QFile file("nonexist01");
622 QVERIFY( !file.exists() );
623 QCOMPARE( file.size(), (qint64)0 );
624 QVERIFY( !file.open(QIODevice::ReadOnly) );
627 void tst_QFile::seek()
629 QFile::remove("newfile.txt");
630 QFile file("newfile.txt");
631 file.open(QIODevice::WriteOnly);
632 QCOMPARE(file.size(), qint64(0));
633 QCOMPARE(file.pos(), qint64(0));
634 QVERIFY(file.seek(10));
635 QCOMPARE(file.pos(), qint64(10));
636 QCOMPARE(file.size(), qint64(0));
638 QFile::remove("newfile.txt");
641 void tst_QFile::setSize()
643 if ( QFile::exists( "createme.txt" ) )
644 QFile::remove( "createme.txt" );
645 QVERIFY( !QFile::exists( "createme.txt" ) );
647 QFile f("createme.txt");
648 QVERIFY(f.open(QIODevice::Truncate | QIODevice::ReadWrite));
656 QCOMPARE(f.size(), (qlonglong)1);
657 bool ok = f.resize(99);
659 QCOMPARE(f.size(), (qlonglong)99);
666 QVERIFY(f.resize(1));
667 QCOMPARE(f.size(), (qlonglong)1);
676 QCOMPARE(f.size(), (qlonglong)1);
677 QVERIFY(f.resize(100));
678 QCOMPARE(f.size(), (qlonglong)100);
679 QVERIFY(f.resize(50));
680 QCOMPARE(f.size(), (qlonglong)50);
683 void tst_QFile::setSizeSeek()
685 QFile::remove("setsizeseek.txt");
686 QFile f("setsizeseek.txt");
687 QVERIFY(f.open(QFile::WriteOnly));
690 QCOMPARE(f.pos(), qint64(4));
692 QCOMPARE(f.pos(), qint64(2));
694 QCOMPARE(f.pos(), qint64(2));
696 QCOMPARE(f.pos(), qint64(0));
698 QCOMPARE(f.pos(), qint64(0));
701 QCOMPARE(f.pos(), qint64(3));
703 QCOMPARE(f.pos(), qint64(2));
706 void tst_QFile::atEnd()
708 QFile f( QFINDTESTDATA("testfile.txt") );
709 QVERIFY(f.open( QIODevice::ReadOnly ));
714 bool end = f.atEnd();
719 void tst_QFile::readLine()
721 QFile f( QFINDTESTDATA("testfile.txt") );
722 QVERIFY(f.open( QIODevice::ReadOnly ));
727 while ( (foo=f.readLine( p, 128 )) > 0 ) {
730 QCOMPARE( p[0], 'T' );
731 QCOMPARE( p[3], 's' );
732 QCOMPARE( p[11], 'i' );
739 void tst_QFile::readLine2()
741 QFile f( QFINDTESTDATA("testfile.txt") );
742 f.open( QIODevice::ReadOnly );
745 QCOMPARE(f.readLine(p, 60), qlonglong(59));
746 QCOMPARE(f.readLine(p, 60), qlonglong(59));
747 memset(p, '@', sizeof(p));
748 QCOMPARE(f.readLine(p, 60), qlonglong(59));
750 QCOMPARE(p[57], '-');
751 QCOMPARE(p[58], '\n');
752 QCOMPARE(p[59], '\0');
753 QCOMPARE(p[60], '@');
756 void tst_QFile::readLineNullInLine()
758 QFile::remove("nullinline.txt");
759 QFile file("nullinline.txt");
760 QVERIFY(file.open(QIODevice::ReadWrite));
761 QVERIFY(file.write("linewith\0null\nanotherline\0withnull\n\0\nnull\0", 42) > 0);
762 QVERIFY(file.flush());
765 QCOMPARE(file.readLine(), QByteArray("linewith\0null\n", 14));
766 QCOMPARE(file.readLine(), QByteArray("anotherline\0withnull\n", 21));
767 QCOMPARE(file.readLine(), QByteArray("\0\n", 2));
768 QCOMPARE(file.readLine(), QByteArray("null\0", 5));
769 QCOMPARE(file.readLine(), QByteArray());
772 void tst_QFile::readAll_data()
774 QTest::addColumn<bool>("textMode");
775 QTest::addColumn<QString>("fileName");
776 QTest::newRow( "TextMode unixfile" ) << true << QFINDTESTDATA("testfile.txt");
777 QTest::newRow( "BinaryMode unixfile" ) << false << QFINDTESTDATA("testfile.txt");
778 QTest::newRow( "TextMode dosfile" ) << true << QFINDTESTDATA("dosfile.txt");
779 QTest::newRow( "BinaryMode dosfile" ) << false << QFINDTESTDATA("dosfile.txt");
780 QTest::newRow( "TextMode bigfile" ) << true << QFINDTESTDATA("tst_qfile.cpp");
781 QTest::newRow( "BinaryMode bigfile" ) << false << QFINDTESTDATA("tst_qfile.cpp");
782 QVERIFY(QFile(QFINDTESTDATA("tst_qfile.cpp")).size() > 64*1024);
785 void tst_QFile::readAll()
787 QFETCH( bool, textMode );
788 QFETCH( QString, fileName );
790 QFile file(fileName);
792 QVERIFY(file.open(QFile::Text | QFile::ReadOnly));
794 QVERIFY(file.open(QFile::ReadOnly));
796 QByteArray a = file.readAll();
798 QVERIFY(file.pos() == 0);
800 QVERIFY(file.bytesAvailable() > 7);
801 QByteArray b = file.read(1);
805 b.append(file.read(5));
806 b.append(file.readAll());
811 void tst_QFile::readAllBuffer()
813 QString fileName = QLatin1String("readAllBuffer.txt");
815 QFile::remove(fileName);
817 QFile writer(fileName);
818 QFile reader(fileName);
820 QByteArray data1("This is arguably a very simple text.");
821 QByteArray data2("This is surely not as simple a test.");
823 QVERIFY( writer.open(QIODevice::ReadWrite | QIODevice::Unbuffered) );
824 QVERIFY( reader.open(QIODevice::ReadOnly) );
826 QCOMPARE( writer.write(data1), qint64(data1.size()) );
827 QVERIFY( writer.seek(0) );
830 result = reader.read(18);
831 QCOMPARE( result.size(), 18 );
833 QCOMPARE( writer.write(data2), qint64(data2.size()) ); // new data, old version buffered in reader
834 QCOMPARE( writer.write(data2), qint64(data2.size()) ); // new data, unbuffered in reader
836 result += reader.readAll();
838 QCOMPARE( result, data1 + data2 );
840 QFile::remove(fileName);
843 void tst_QFile::readAllStdin()
845 #if defined(Q_OS_WINCE)
846 QSKIP("Currently no stdin/out supported for Windows CE");
848 #if defined(QT_NO_PROCESS)
849 QSKIP("Qt was compiled with QT_NO_PROCESS");
851 QByteArray lotsOfData(1024, '@'); // 10 megs
854 process.start("stdinprocess/stdinprocess all");
855 QVERIFY( process.waitForStarted() );
856 for (int i = 0; i < 5; ++i) {
858 process.write(lotsOfData);
859 while (process.bytesToWrite() > 0) {
860 QVERIFY(process.waitForBytesWritten());
864 process.closeWriteChannel();
865 process.waitForFinished();
866 QCOMPARE(process.readAll().size(), lotsOfData.size() * 5);
870 void tst_QFile::readLineStdin()
872 #if defined(Q_OS_WINCE)
873 QSKIP("Currently no stdin/out supported for Windows CE");
875 #if defined(QT_NO_PROCESS)
876 QSKIP("Qt was compiled with QT_NO_PROCESS");
879 QByteArray lotsOfData(1024, '@'); // 10 megs
880 for (int i = 0; i < lotsOfData.size(); ++i) {
882 lotsOfData[i] = '\n';
884 lotsOfData[i] = char('0' + i % 32);
887 for (int i = 0; i < 2; ++i) {
889 process.start((QString("stdinprocess/stdinprocess line %1").arg(i)), QIODevice::Text | QIODevice::ReadWrite);
890 for (int i = 0; i < 5; ++i) {
892 process.write(lotsOfData);
893 while (process.bytesToWrite() > 0) {
894 QVERIFY(process.waitForBytesWritten());
898 process.closeWriteChannel();
899 QVERIFY(process.waitForFinished(5000));
901 QByteArray array = process.readAll();
902 QCOMPARE(array.size(), lotsOfData.size() * 5);
903 for (int i = 0; i < array.size(); ++i) {
905 QCOMPARE(char(array[i]), '\n');
907 QCOMPARE(char(array[i]), char('0' + i % 32));
913 void tst_QFile::readLineStdin_lineByLine()
915 #if defined(Q_OS_WINCE)
916 QSKIP("Currently no stdin/out supported for Windows CE");
918 #if defined(QT_NO_PROCESS)
919 QSKIP("Qt was compiled with QT_NO_PROCESS");
921 for (int i = 0; i < 2; ++i) {
923 process.start(QString("stdinprocess/stdinprocess line %1").arg(i), QIODevice::Text | QIODevice::ReadWrite);
924 QVERIFY(process.waitForStarted());
926 for (int j = 0; j < 3; ++j) {
927 QByteArray line = "line " + QByteArray::number(j) + "\n";
928 QCOMPARE(process.write(line), qint64(line.size()));
929 QVERIFY(process.waitForBytesWritten(2000));
930 if (process.bytesAvailable() == 0)
931 QVERIFY(process.waitForReadyRead(2000));
932 QCOMPARE(process.readAll(), line);
935 process.closeWriteChannel();
936 QVERIFY(process.waitForFinished(5000));
941 void tst_QFile::text()
943 // dosfile.txt is a binary CRLF file
944 QFile file(QFINDTESTDATA("dosfile.txt"));
945 QVERIFY(file.open(QFile::Text | QFile::ReadOnly));
946 QCOMPARE(file.readLine(),
947 QByteArray("/dev/system/root / reiserfs acl,user_xattr 1 1\n"));
948 QCOMPARE(file.readLine(),
949 QByteArray("/dev/sda1 /boot ext3 acl,user_xattr 1 2\n"));
950 file.ungetChar('\n');
952 QCOMPARE(file.readLine().constData(), QByteArray("2\n").constData());
955 void tst_QFile::missingEndOfLine()
957 QFile file(QFINDTESTDATA("noendofline.txt"));
958 QVERIFY(file.open(QFile::ReadOnly));
961 while (!file.atEnd()) {
969 void tst_QFile::readBlock()
971 QFile f( QFINDTESTDATA("testfile.txt") );
972 f.open( QIODevice::ReadOnly );
976 length = f.read( p, 256 );
978 QCOMPARE( length, 245 );
979 QCOMPARE( p[59], 'D' );
980 QCOMPARE( p[178], 'T' );
981 QCOMPARE( p[199], 'l' );
984 void tst_QFile::getch()
986 QFile f( QFINDTESTDATA("testfile.txt") );
987 f.open( QIODevice::ReadOnly );
991 while (f.getChar(&c)) {
992 QCOMPARE(f.pos(), qint64(i + 1));
1001 void tst_QFile::ungetChar()
1003 QFile f(QFINDTESTDATA("testfile.txt"));
1004 QVERIFY(f.open(QIODevice::ReadOnly));
1006 QByteArray array = f.readLine();
1007 QCOMPARE(array.constData(), "----------------------------------------------------------\n");
1010 array = f.readLine();
1011 QCOMPARE(array.constData(), "\n");
1017 array = f.readLine();
1018 QCOMPARE(array.constData(), "--\n");
1020 QFile::remove("genfile.txt");
1021 QFile out("genfile.txt");
1022 QVERIFY(out.open(QIODevice::ReadWrite));
1025 QCOMPARE(out.readAll().constData(), "123");
1029 QCOMPARE(out.readAll().constData(), "124");
1034 QCOMPARE(out.read(buf, sizeof(buf)), qint64(3));
1035 QCOMPARE(buf[0], '1');
1036 QCOMPARE(buf[1], '2');
1037 QCOMPARE(buf[2], '4');
1040 void tst_QFile::invalidFile_data()
1042 QTest::addColumn<QString>("fileName");
1043 #if !defined(Q_OS_WIN)
1044 QTest::newRow( "x11" ) << QString( "qwe//" );
1046 QTest::newRow( "colon1" ) << QString( "fail:invalid" );
1047 QTest::newRow( "colon2" ) << QString( "f:ail:invalid" );
1048 QTest::newRow( "colon3" ) << QString( ":failinvalid" );
1049 QTest::newRow( "forwardslash" ) << QString( "fail/invalid" );
1050 QTest::newRow( "asterisk" ) << QString( "fail*invalid" );
1051 QTest::newRow( "questionmark" ) << QString( "fail?invalid" );
1052 QTest::newRow( "quote" ) << QString( "fail\"invalid" );
1053 QTest::newRow( "lt" ) << QString( "fail<invalid" );
1054 QTest::newRow( "gt" ) << QString( "fail>invalid" );
1055 QTest::newRow( "pipe" ) << QString( "fail|invalid" );
1059 void tst_QFile::invalidFile()
1061 QFETCH( QString, fileName );
1062 QFile f( fileName );
1063 QVERIFY( !f.open( QIODevice::ReadWrite ) );
1066 void tst_QFile::createFile()
1068 if ( QFile::exists( "createme.txt" ) )
1069 QFile::remove( "createme.txt" );
1070 QVERIFY( !QFile::exists( "createme.txt" ) );
1072 QFile f( "createme.txt" );
1073 QVERIFY( f.open( QIODevice::WriteOnly ) );
1075 QVERIFY( QFile::exists( "createme.txt" ) );
1078 void tst_QFile::append()
1080 const QString name("appendme.txt");
1081 if (QFile::exists(name))
1082 QFile::remove(name);
1083 QVERIFY(!QFile::exists(name));
1086 QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate));
1090 QVERIFY(f.open(QIODevice::Append));
1091 QVERIFY(f.pos() == 1);
1094 QCOMPARE(int(f.size()), 2);
1097 void tst_QFile::permissions_data()
1099 QTest::addColumn<QString>("file");
1100 QTest::addColumn<uint>("perms");
1101 QTest::addColumn<bool>("expected");
1102 QTest::addColumn<bool>("create");
1104 QTest::newRow("data0") << QCoreApplication::instance()->applicationFilePath() << uint(QFile::ExeUser) << true << false;
1105 QTest::newRow("data1") << QFINDTESTDATA("tst_qfile.cpp") << uint(QFile::ReadUser) << true << false;
1106 QTest::newRow("readonly") << QFINDTESTDATA("readonlyfile") << uint(QFile::WriteUser) << false << false;
1108 QTest::newRow("longfile") << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
1109 "longFileNamelongFileNamelongFileNamelongFileName"
1110 "longFileNamelongFileNamelongFileNamelongFileName"
1111 "longFileNamelongFileNamelongFileNamelongFileName"
1112 "longFileNamelongFileNamelongFileNamelongFileName.txt") << uint(QFile::ReadUser) << true << true;
1114 QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::ReadUser) << true << false;
1115 QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::WriteUser) << false << false;
1116 QTest::newRow("resource3") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::ExeUser) << false << false;
1119 void tst_QFile::permissions()
1121 QFETCH(QString, file);
1122 QFETCH(uint, perms);
1123 QFETCH(bool, expected);
1124 QFETCH(bool, create);
1127 QVERIFY(fc.open(QFile::WriteOnly));
1128 QVERIFY(fc.write("hello\n"));
1133 QFile::Permissions memberResult = f.permissions() & perms;
1134 QFile::Permissions staticResult = QFile::permissions(file) & perms;
1137 QFile::remove(file);
1141 if (qt_ntfs_permission_lookup)
1142 QEXPECT_FAIL("readonly", "QTBUG-25630", Abort);
1144 QCOMPARE((memberResult == QFile::Permissions(perms)), expected);
1145 QCOMPARE((staticResult == QFile::Permissions(perms)), expected);
1148 void tst_QFile::permissionsNtfs_data()
1153 void tst_QFile::permissionsNtfs()
1156 QScopedValueRollback<int> ntfsMode(qt_ntfs_permission_lookup);
1157 qt_ntfs_permission_lookup++;
1160 QSKIP("windows test");
1164 void tst_QFile::setPermissions()
1166 if ( QFile::exists( "createme.txt" ) )
1167 QFile::remove( "createme.txt" );
1168 QVERIFY( !QFile::exists( "createme.txt" ) );
1170 QFile f("createme.txt");
1171 QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate));
1175 QFile::Permissions perms(QFile::WriteUser | QFile::ReadUser);
1176 QVERIFY(f.setPermissions(perms));
1177 QVERIFY((f.permissions() & perms) == perms);
1181 void tst_QFile::copy()
1183 QFile::setPermissions("tst_qfile_copy.cpp", QFile::WriteUser);
1184 QFile::remove("tst_qfile_copy.cpp");
1185 QFile::remove("test2");
1186 QVERIFY(QFile::copy(QFINDTESTDATA("tst_qfile.cpp"), "tst_qfile_copy.cpp"));
1187 QFile in1(QFINDTESTDATA("tst_qfile.cpp")), in2("tst_qfile_copy.cpp");
1188 QVERIFY(in1.open(QFile::ReadOnly));
1189 QVERIFY(in2.open(QFile::ReadOnly));
1190 QByteArray data1 = in1.readAll(), data2 = in2.readAll();
1191 QCOMPARE(data1, data2);
1192 QFile::remove( "main_copy.cpp" );
1194 QFile::copy(QDir::currentPath(), QDir::currentPath() + QLatin1String("/test2"));
1197 void tst_QFile::copyAfterFail()
1199 QFile file1("file-to-be-copied.txt");
1200 QFile file2("existing-file.txt");
1202 QVERIFY(file1.open(QIODevice::ReadWrite) && "(test-precondition)");
1203 QVERIFY(file2.open(QIODevice::ReadWrite) && "(test-precondition)");
1205 QVERIFY(!QFile::exists("copied-file-1.txt") && "(test-precondition)");
1206 QVERIFY(!QFile::exists("copied-file-2.txt") && "(test-precondition)");
1208 QVERIFY(!file1.copy("existing-file.txt"));
1209 QCOMPARE(file1.error(), QFile::CopyError);
1211 QVERIFY(file1.copy("copied-file-1.txt"));
1212 QVERIFY(!file1.isOpen());
1213 QCOMPARE(file1.error(), QFile::NoError);
1215 QVERIFY(!file1.copy("existing-file.txt"));
1216 QCOMPARE(file1.error(), QFile::CopyError);
1218 QVERIFY(file1.copy("copied-file-2.txt"));
1219 QVERIFY(!file1.isOpen());
1220 QCOMPARE(file1.error(), QFile::NoError);
1222 QVERIFY(QFile::exists("copied-file-1.txt"));
1223 QVERIFY(QFile::exists("copied-file-2.txt"));
1225 QVERIFY(QFile::remove("file-to-be-copied.txt") && "(test-cleanup)");
1226 QVERIFY(QFile::remove("existing-file.txt") && "(test-cleanup)");
1227 QVERIFY(QFile::remove("copied-file-1.txt") && "(test-cleanup)");
1228 QVERIFY(QFile::remove("copied-file-2.txt") && "(test-cleanup)");
1231 void tst_QFile::copyRemovesTemporaryFile() const
1233 const QString newName(QLatin1String("copyRemovesTemporaryFile"));
1234 QVERIFY(QFile::copy(QFINDTESTDATA("forCopying.txt"), newName));
1236 QVERIFY(!QFile::exists(QFINDTESTDATA("qt_temp.XXXXXX")));
1237 QVERIFY(QFile::remove(newName));
1240 void tst_QFile::copyShouldntOverwrite()
1242 // Copy should not overwrite existing files.
1243 QFile::remove("tst_qfile.cpy");
1244 QFile file(QFINDTESTDATA("tst_qfile.cpp"));
1245 QVERIFY(file.copy("tst_qfile.cpy"));
1247 bool ok = QFile::setPermissions("tst_qfile.cpy", QFile::WriteOther);
1249 QVERIFY(!file.copy("tst_qfile.cpy"));
1250 QFile::remove("tst_qfile.cpy");
1253 void tst_QFile::copyFallback()
1255 // Using a resource file to trigger QFile::copy's fallback handling
1256 QFile file(":/copy-fallback.qrc");
1257 QFile::remove("file-copy-destination.txt");
1259 QVERIFY2(file.exists(), "test precondition");
1260 QVERIFY2(!QFile::exists("file-copy-destination.txt"), "test precondition");
1262 // Fallback copy of closed file.
1263 QVERIFY(file.copy("file-copy-destination.txt"));
1264 QVERIFY(QFile::exists("file-copy-destination.txt"));
1265 QVERIFY(!file.isOpen());
1268 // Need to reset permissions on Windows to be able to delete
1269 QVERIFY(QFile::setPermissions("file-copy-destination.txt",
1270 QFile::WriteOther));
1272 // Need to reset permissions on Windows to be able to delete
1273 QVERIFY(QFile::setPermissions("file-copy-destination.txt",
1274 QFile::ReadOwner | QFile::WriteOwner));
1276 QVERIFY(QFile::remove("file-copy-destination.txt"));
1278 // Fallback copy of open file.
1279 QVERIFY(file.open(QIODevice::ReadOnly));
1280 QVERIFY(file.copy("file-copy-destination.txt"));
1281 QVERIFY(QFile::exists("file-copy-destination.txt"));
1282 QVERIFY(!file.isOpen());
1285 QFile::remove("file-copy-destination.txt");
1289 #include <objbase.h>
1293 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
1294 static QString getWorkingDirectoryForLink(const QString &linkFileName)
1296 bool neededCoInit = false;
1300 HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
1301 if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized
1302 neededCoInit = true;
1304 hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
1307 if (SUCCEEDED(hres)) { // Get pointer to the IPersistFile interface.
1309 hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf);
1310 if (SUCCEEDED(hres)) {
1311 hres = ppf->Load((LPOLESTR)linkFileName.utf16(), STGM_READ);
1312 //The original path of the link is retrieved. If the file/folder
1313 //was moved, the return value still have the old path.
1314 if(SUCCEEDED(hres)) {
1315 wchar_t szGotPath[MAX_PATH];
1316 if (psl->GetWorkingDirectory(szGotPath, MAX_PATH) == NOERROR)
1317 ret = QString::fromWCharArray(szGotPath);
1332 void tst_QFile::link()
1334 QFile::remove("myLink.lnk");
1336 QFileInfo info1(QFINDTESTDATA("tst_qfile.cpp"));
1337 QString referenceTarget = QDir::cleanPath(info1.absoluteFilePath());
1339 QVERIFY(QFile::link(QFINDTESTDATA("tst_qfile.cpp"), "myLink.lnk"));
1341 QFileInfo info2("myLink.lnk");
1342 QVERIFY(info2.isSymLink());
1343 QCOMPARE(info2.symLinkTarget(), referenceTarget);
1345 QFile link("myLink.lnk");
1346 QVERIFY(link.open(QIODevice::ReadOnly));
1347 QCOMPARE(link.symLinkTarget(), referenceTarget);
1350 QCOMPARE(QFile::symLinkTarget("myLink.lnk"), referenceTarget);
1352 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
1353 QString wd = getWorkingDirectoryForLink(info2.absoluteFilePath());
1354 QCOMPARE(QDir::fromNativeSeparators(wd), QDir::cleanPath(info1.absolutePath()));
1357 QVERIFY(QFile::remove(info2.absoluteFilePath()));
1360 void tst_QFile::linkToDir()
1362 QFile::remove("myLinkToDir.lnk");
1365 QFileInfo info1("myDir");
1366 QVERIFY(QFile::link("myDir", "myLinkToDir.lnk"));
1367 QFileInfo info2("myLinkToDir.lnk");
1368 #if !(defined Q_OS_HPUX && defined(__ia64))
1369 // absurd HP-UX filesystem bug on gravlaks - checking if a symlink
1370 // resolves or not alters the file system to make the broken symlink
1372 QVERIFY(info2.isSymLink());
1374 QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath());
1375 QVERIFY(QFile::remove(info2.absoluteFilePath()));
1376 QFile::remove("myLinkToDir.lnk");
1380 void tst_QFile::absolutePathLinkToRelativePath()
1382 QFile::remove("myDir/test.txt");
1383 QFile::remove("myDir/myLink.lnk");
1386 QFile("myDir/test.txt").open(QFile::WriteOnly);
1389 QVERIFY(QFile::link("test.txt", "myDir/myLink.lnk"));
1391 QVERIFY(QFile::link("myDir/test.txt", "myDir/myLink.lnk"));
1393 QEXPECT_FAIL("", "Symlinking using relative paths is currently different on Windows and Unix", Continue);
1394 QCOMPARE(QFileInfo(QFile(QFileInfo("myDir/myLink.lnk").absoluteFilePath()).symLinkTarget()).absoluteFilePath(),
1395 QFileInfo("myDir/test.txt").absoluteFilePath());
1397 QFile::remove("myDir/test.txt");
1398 QFile::remove("myDir/myLink.lnk");
1402 void tst_QFile::readBrokenLink()
1404 QFile::remove("myLink2.lnk");
1405 QFileInfo info1("file12");
1406 QVERIFY(QFile::link("file12", "myLink2.lnk"));
1407 QFileInfo info2("myLink2.lnk");
1408 QVERIFY(info2.isSymLink());
1409 QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath());
1410 QVERIFY(QFile::remove(info2.absoluteFilePath()));
1411 QVERIFY(QFile::link("ole/..", "myLink2.lnk"));
1412 QCOMPARE(QFileInfo("myLink2.lnk").symLinkTarget(), QDir::currentPath());
1415 void tst_QFile::readTextFile_data()
1417 QTest::addColumn<QByteArray>("in");
1418 QTest::addColumn<QByteArray>("out");
1420 QTest::newRow("empty") << QByteArray() << QByteArray();
1421 QTest::newRow("a") << QByteArray("a") << QByteArray("a");
1422 QTest::newRow("a\\rb") << QByteArray("a\rb") << QByteArray("ab");
1423 QTest::newRow("\\n") << QByteArray("\n") << QByteArray("\n");
1424 QTest::newRow("\\r\\n") << QByteArray("\r\n") << QByteArray("\n");
1425 QTest::newRow("\\r") << QByteArray("\r") << QByteArray();
1426 QTest::newRow("twolines") << QByteArray("Hello\r\nWorld\r\n") << QByteArray("Hello\nWorld\n");
1427 QTest::newRow("twolines no endline") << QByteArray("Hello\r\nWorld") << QByteArray("Hello\nWorld");
1430 void tst_QFile::readTextFile()
1432 QFETCH(QByteArray, in);
1433 QFETCH(QByteArray, out);
1435 QFile winfile("winfile.txt");
1436 QVERIFY(winfile.open(QFile::WriteOnly | QFile::Truncate));
1440 QVERIFY(winfile.open(QFile::ReadOnly));
1441 QCOMPARE(winfile.readAll(), in);
1444 QVERIFY(winfile.open(QFile::ReadOnly | QFile::Text));
1445 QCOMPARE(winfile.readAll(), out);
1448 void tst_QFile::readTextFile2()
1451 QFile file(QFINDTESTDATA("testlog.txt"));
1452 QVERIFY(file.open(QIODevice::ReadOnly));
1457 QFile file(QFINDTESTDATA("testlog.txt"));
1458 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
1463 void tst_QFile::writeTextFile_data()
1465 QTest::addColumn<QByteArray>("in");
1467 QTest::newRow("empty") << QByteArray();
1468 QTest::newRow("a") << QByteArray("a");
1469 QTest::newRow("a\\rb") << QByteArray("a\rb");
1470 QTest::newRow("\\n") << QByteArray("\n");
1471 QTest::newRow("\\r\\n") << QByteArray("\r\n");
1472 QTest::newRow("\\r") << QByteArray("\r");
1473 QTest::newRow("twolines crlf") << QByteArray("Hello\r\nWorld\r\n");
1474 QTest::newRow("twolines crlf no endline") << QByteArray("Hello\r\nWorld");
1475 QTest::newRow("twolines lf") << QByteArray("Hello\nWorld\n");
1476 QTest::newRow("twolines lf no endline") << QByteArray("Hello\nWorld");
1477 QTest::newRow("mixed") << QByteArray("this\nis\r\na\nmixed\r\nfile\n");
1480 void tst_QFile::writeTextFile()
1482 QFETCH(QByteArray, in);
1484 QFile file("textfile.txt");
1485 QVERIFY(file.open(QFile::WriteOnly | QFile::Truncate | QFile::Text));
1486 QByteArray out = in;
1488 out.replace('\n', "\r\n");
1490 QCOMPARE(file.write(in), qlonglong(in.size()));
1493 file.open(QFile::ReadOnly);
1494 QCOMPARE(file.readAll(), out);
1497 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
1498 void tst_QFile::largeUncFileSupport()
1500 qint64 size = Q_INT64_C(8589934592);
1501 qint64 dataOffset = Q_INT64_C(8589914592);
1502 QByteArray knownData("LargeFile content at offset 8589914592");
1503 QString largeFile("//" + QtNetworkSettings::winServerName() + "/testsharelargefile/file.bin");
1506 // 1) Native file handling.
1507 QFile file(largeFile);
1508 QCOMPARE(file.size(), size);
1509 QVERIFY(file.open(QIODevice::ReadOnly));
1510 QCOMPARE(file.size(), size);
1511 QVERIFY(file.seek(dataOffset));
1512 QCOMPARE(file.read(knownData.size()), knownData);
1515 // 2) stdlib file handling.
1517 FILE *fh = fopen(QFile::encodeName(largeFile).data(), "rb");
1518 QVERIFY(file.open(fh, QIODevice::ReadOnly));
1519 QCOMPARE(file.size(), size);
1520 QVERIFY(file.seek(dataOffset));
1521 QCOMPARE(file.read(knownData.size()), knownData);
1525 // 3) stdio file handling.
1527 FILE *fh = fopen(QFile::encodeName(largeFile).data(), "rb");
1528 int fd = int(_fileno(fh));
1529 QVERIFY(file.open(fd, QIODevice::ReadOnly));
1530 QCOMPARE(file.size(), size);
1531 QVERIFY(file.seek(dataOffset));
1532 QCOMPARE(file.read(knownData.size()), knownData);
1538 void tst_QFile::tailFile()
1540 QSKIP("File change notifications are so far unsupported.");
1542 QFile file("tail.txt");
1543 QVERIFY(file.open(QFile::WriteOnly | QFile::Append));
1545 QFile tailFile("tail.txt");
1546 QVERIFY(tailFile.open(QFile::ReadOnly));
1547 tailFile.seek(file.size());
1549 QSignalSpy readSignalSpy(&tailFile, SIGNAL(readyRead()));
1550 QVERIFY(readSignalSpy.isValid());
1554 QTestEventLoop::instance().enterLoop(5);
1556 QVERIFY(!QTestEventLoop::instance().timeout());
1557 QCOMPARE(readSignalSpy.count(), 1);
1560 void tst_QFile::flush()
1562 QString fileName("stdfile.txt");
1564 QFile::remove(fileName);
1567 QFile file(fileName);
1568 QVERIFY(file.open(QFile::WriteOnly));
1569 QCOMPARE(file.write("abc", 3),qint64(3));
1573 QFile file(fileName);
1574 QVERIFY(file.open(QFile::WriteOnly | QFile::Append));
1575 QCOMPARE(file.pos(), qlonglong(3));
1576 QCOMPARE(file.write("def", 3), qlonglong(3));
1577 QCOMPARE(file.pos(), qlonglong(6));
1581 QFile file("stdfile.txt");
1582 QVERIFY(file.open(QFile::ReadOnly));
1583 QCOMPARE(file.readAll(), QByteArray("abcdef"));
1586 QFile::remove(fileName);
1589 void tst_QFile::bufferedRead()
1591 QFile::remove("stdfile.txt");
1593 QFile file("stdfile.txt");
1594 QVERIFY(file.open(QFile::WriteOnly));
1595 file.write("abcdef");
1598 #if defined(Q_OS_WINCE)
1599 FILE *stdFile = fopen((QCoreApplication::applicationDirPath() + "/stdfile.txt").toLatin1() , "r");
1601 FILE *stdFile = fopen("stdfile.txt", "r");
1605 QCOMPARE(int(fread(&c, 1, 1, stdFile)), 1);
1607 QCOMPARE(int(ftell(stdFile)), 1);
1611 QVERIFY(file.open(stdFile, QFile::ReadOnly));
1612 QCOMPARE(file.pos(), qlonglong(1));
1613 QCOMPARE(file.read(&c, 1), qlonglong(1));
1615 QCOMPARE(file.pos(), qlonglong(2));
1621 void tst_QFile::isSequential()
1624 QSKIP("Unix only test.");
1626 QFile zero("/dev/null");
1627 QVERIFY(zero.open(QFile::ReadOnly));
1628 QVERIFY(zero.isSequential());
1631 void tst_QFile::encodeName()
1633 QCOMPARE(QFile::encodeName(QString::null), QByteArray());
1636 void tst_QFile::truncate()
1638 for (int i = 0; i < 2; ++i) {
1639 QFile file("truncate.txt");
1640 QVERIFY(file.open(QFile::WriteOnly));
1641 file.write(QByteArray(200, '@'));
1644 QVERIFY(file.open((i ? QFile::WriteOnly : QFile::ReadWrite) | QFile::Truncate));
1645 file.write(QByteArray(100, '$'));
1648 QVERIFY(file.open(QFile::ReadOnly));
1649 QCOMPARE(file.readAll(), QByteArray(100, '$'));
1653 void tst_QFile::seekToPos()
1656 QFile file("seekToPos.txt");
1657 QVERIFY(file.open(QFile::WriteOnly));
1658 file.write("a\r\nb\r\nc\r\n");
1662 QFile file("seekToPos.txt");
1663 QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
1666 QVERIFY(file.getChar(&c));
1669 QCOMPARE(file.pos(), qint64(3));
1670 file.seek(file.pos());
1671 QCOMPARE(file.pos(), qint64(3));
1674 file.seek(file.pos());
1675 QCOMPARE(file.pos(), qint64(1));
1679 void tst_QFile::seekAfterEndOfFile()
1681 QLatin1String filename("seekAfterEof.dat");
1682 QFile::remove(filename);
1684 QFile file(filename);
1685 QVERIFY(file.open(QFile::WriteOnly));
1687 QCOMPARE(file.size(), qint64(4));
1690 QCOMPARE(file.size(), qint64(12));
1693 QCOMPARE(file.size(), qint64(12));
1696 QCOMPARE(file.size(), qint64(20));
1700 QFile file(filename);
1701 QVERIFY(file.open(QFile::ReadOnly));
1702 QByteArray contents = file.readAll();
1703 QCOMPARE(contents.left(12), QByteArray("abcdefghijkl", 12));
1704 //bytes 12-15 are uninitialised so we don't care what they read as.
1705 QCOMPARE(contents.mid(16), QByteArray("----", 4));
1707 QFile::remove(filename);
1710 void tst_QFile::FILEReadWrite()
1712 // Tests modifying a file. First creates it then reads in 4 bytes and then overwrites these
1713 // 4 bytes with new values. At the end check to see the file contains the new values.
1715 QFile::remove("FILEReadWrite.txt");
1719 QFile f("FILEReadWrite.txt");
1720 QVERIFY(f.open(QFile::WriteOnly));
1750 FILE *fp = fopen(qPrintable(QCoreApplication::applicationDirPath() + "\\FILEReadWrite.txt"), "r+b");
1752 FILE *fp = fopen("FILEReadWrite.txt", "r+b");
1756 QVERIFY(file.open(fp, QFile::ReadWrite));
1757 QDataStream sfile(&file) ;
1759 qint8 var1,var2,var3,var4;
1760 while (!sfile.atEnd())
1762 qint64 base = file.pos();
1764 QCOMPARE(file.pos(), base + 0);
1766 QCOMPARE(file.pos(), base + 1);
1767 file.flush(); // flushing should not change the base
1768 QCOMPARE(file.pos(), base + 1);
1770 QCOMPARE(file.pos(), base + 2);
1772 QCOMPARE(file.pos(), base + 3);
1774 QCOMPARE(file.pos(), base + 4);
1775 file.seek(file.pos() - 4) ; // Move it back 4, for we are going to write new values based on old ones
1776 QCOMPARE(file.pos(), base + 0);
1777 sfile << qint8(var1 + 5);
1778 QCOMPARE(file.pos(), base + 1);
1779 sfile << qint8(var2 + 5);
1780 QCOMPARE(file.pos(), base + 2);
1781 sfile << qint8(var3 + 5);
1782 QCOMPARE(file.pos(), base + 3);
1783 sfile << qint8(var4 + 5);
1784 QCOMPARE(file.pos(), base + 4);
1790 // check modified file
1792 QFile f("FILEReadWrite.txt");
1793 QVERIFY(f.open(QFile::ReadOnly));
1797 QCOMPARE(c, (qint8)5);
1799 QCOMPARE(c, (qint8)6);
1801 QCOMPARE(c, (qint8)7);
1803 QCOMPARE(c, (qint8)8);
1805 QCOMPARE(c, (qint8)9);
1807 QCOMPARE(c, (qint8)10);
1809 QCOMPARE(c, (qint8)11);
1811 QCOMPARE(c, (qint8)12);
1813 QCOMPARE(c, (qint8)13);
1815 QCOMPARE(c, (qint8)14);
1817 QCOMPARE(c, (qint8)15);
1819 QCOMPARE(c, (qint8)16);
1823 QFile::remove("FILEReadWrite.txt");
1828 #include <qglobal.h>
1830 #define FILESIZE 0x10000000f
1831 void tst_QFile::largeFileSupport()
1834 QSKIP("Solaris does not support statfs");
1836 qlonglong sizeNeeded = 2147483647;
1839 qlonglong freespace = qlonglong(0);
1841 _ULARGE_INTEGER free;
1842 if (::GetDiskFreeSpaceEx((wchar_t*)QDir::currentPath().utf16(), &free, 0, 0))
1843 freespace = free.QuadPart;
1844 if (freespace != 0) {
1845 #elif defined(Q_OS_IRIX)
1847 if (statfs(QDir::currentPath().local8Bit(), &info, sizeof(struct statfs), 0) == 0) {
1848 freespace = qlonglong(info.f_bfree * info.f_bsize);
1851 if (statfs(const_cast<char *>(QDir::currentPath().toLocal8Bit().constData()), &info) == 0) {
1852 freespace = qlonglong(info.f_bavail * info.f_bsize);
1854 if (freespace > sizeNeeded) {
1855 QFile bigFile("bigfile");
1856 if (bigFile.open(QFile::ReadWrite)) {
1857 char c[BUFFSIZE] = {'a'};
1858 QVERIFY(bigFile.write(c, BUFFSIZE) == BUFFSIZE);
1859 qlonglong oldPos = bigFile.pos();
1860 QVERIFY(bigFile.resize(sizeNeeded));
1861 QCOMPARE(oldPos, bigFile.pos());
1862 QVERIFY(bigFile.seek(sizeNeeded - BUFFSIZE));
1863 QVERIFY(bigFile.write(c, BUFFSIZE) == BUFFSIZE);
1866 if (bigFile.open(QFile::ReadOnly)) {
1867 QVERIFY(bigFile.read(c, BUFFSIZE) == BUFFSIZE);
1869 for (i=0; i<BUFFSIZE; i++)
1870 QCOMPARE(c[i], 'a');
1871 QVERIFY(bigFile.seek(sizeNeeded - BUFFSIZE));
1872 QVERIFY(bigFile.read(c, BUFFSIZE) == BUFFSIZE);
1873 for (i=0; i<BUFFSIZE; i++)
1874 QCOMPARE(c[i], 'a');
1876 QVERIFY(bigFile.remove());
1878 QVERIFY(bigFile.remove());
1879 QFAIL("Could not reopen file");
1882 QFAIL("Could not open file");
1885 QSKIP("Not enough space to run test");
1888 QFAIL("Could not determin disk space");
1894 void tst_QFile::i18nFileName_data()
1896 QTest::addColumn<QString>("fileName");
1898 QTest::newRow( "01" ) << QString::fromUtf8("xxxxxxx.txt");
1901 void tst_QFile::i18nFileName()
1903 QFETCH(QString, fileName);
1904 if (QFile::exists(fileName)) {
1905 QVERIFY(QFile::remove(fileName));
1908 QFile file(fileName);
1909 QVERIFY(file.open(QFile::WriteOnly | QFile::Text));
1910 QTextStream ts(&file);
1911 ts.setCodec("UTF-8");
1912 ts << fileName << endl;
1915 QFile file(fileName);
1916 QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
1917 QTextStream ts(&file);
1918 ts.setCodec("UTF-8");
1919 QString line = ts.readLine();
1920 QCOMPARE(line, fileName);
1922 QVERIFY(QFile::remove(fileName));
1926 void tst_QFile::longFileName_data()
1928 QTest::addColumn<QString>("fileName");
1930 QTest::newRow( "16 chars" ) << QString::fromLatin1("longFileName.txt");
1931 QTest::newRow( "52 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName.txt");
1932 QTest::newRow( "148 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
1933 "longFileNamelongFileNamelongFileNamelongFileName"
1934 "longFileNamelongFileNamelongFileNamelongFileName.txt");
1935 QTest::newRow( "244 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
1936 "longFileNamelongFileNamelongFileNamelongFileName"
1937 "longFileNamelongFileNamelongFileNamelongFileName"
1938 "longFileNamelongFileNamelongFileNamelongFileName"
1939 "longFileNamelongFileNamelongFileNamelongFileName.txt");
1940 QTest::newRow( "244 chars to absolutepath" ) << QFileInfo(QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
1941 "longFileNamelongFileNamelongFileNamelongFileName"
1942 "longFileNamelongFileNamelongFileNamelongFileName"
1943 "longFileNamelongFileNamelongFileNamelongFileName"
1944 "longFileNamelongFileNamelongFileNamelongFileName.txt")).absoluteFilePath();
1945 /* needs to be put on a windows 2000 > test machine
1946 QTest::newRow( "244 chars on UNC" ) << QString::fromLatin1("//arsia/D/troll/tmp/longFileNamelongFileNamelongFileNamelongFileName"
1947 "longFileNamelongFileNamelongFileNamelongFileName"
1948 "longFileNamelongFileNamelongFileNamelongFileName"
1949 "longFileNamelongFileNamelongFileNamelongFileName"
1950 "longFileNamelongFileNamelongFileNamelongFileName.txt");*/
1953 void tst_QFile::longFileName()
1955 QFETCH(QString, fileName);
1956 if (QFile::exists(fileName)) {
1957 QVERIFY(QFile::remove(fileName));
1960 QFile file(fileName);
1961 #if defined(Q_OS_WINCE)
1962 QEXPECT_FAIL("244 chars", "Full pathname must be less than 260 chars", Abort);
1963 QEXPECT_FAIL("244 chars to absolutepath", "Full pathname must be less than 260 chars", Abort);
1965 QVERIFY(file.open(QFile::WriteOnly | QFile::Text));
1966 QTextStream ts(&file);
1967 ts << fileName << endl;
1970 QFile file(fileName);
1971 QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
1972 QTextStream ts(&file);
1973 QString line = ts.readLine();
1974 QCOMPARE(line, fileName);
1976 QString newName = fileName + QLatin1String("1");
1978 QVERIFY(QFile::copy(fileName, newName));
1979 QFile file(newName);
1980 QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
1981 QTextStream ts(&file);
1982 QString line = ts.readLine();
1983 QCOMPARE(line, fileName);
1986 QVERIFY(QFile::remove(newName));
1988 QVERIFY(QFile::rename(fileName, newName));
1989 QFile file(newName);
1990 QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
1991 QTextStream ts(&file);
1992 QString line = ts.readLine();
1993 QCOMPARE(line, fileName);
1995 QVERIFY(QFile::exists(newName));
1996 QVERIFY(QFile::remove(newName));
1999 #ifdef QT_BUILD_INTERNAL
2000 class MyEngine : public QAbstractFileEngine
2003 MyEngine(int n) { number = n; }
2004 virtual ~MyEngine() {}
2006 void setFileName(const QString &) {}
2007 bool open(QIODevice::OpenMode) { return false; }
2008 bool close() { return false; }
2009 bool flush() { return false; }
2010 qint64 size() const { return 123 + number; }
2011 qint64 at() const { return -1; }
2012 bool seek(qint64) { return false; }
2013 bool isSequential() const { return false; }
2014 qint64 read(char *, qint64) { return -1; }
2015 qint64 write(const char *, qint64) { return -1; }
2016 bool remove() { return false; }
2017 bool copy(const QString &) { return false; }
2018 bool rename(const QString &) { return false; }
2019 bool link(const QString &) { return false; }
2020 bool mkdir(const QString &, bool) const { return false; }
2021 bool rmdir(const QString &, bool) const { return false; }
2022 bool setSize(qint64) { return false; }
2023 QStringList entryList(QDir::Filters, const QStringList &) const { return QStringList(); }
2024 bool caseSensitive() const { return false; }
2025 bool isRelativePath() const { return false; }
2026 FileFlags fileFlags(FileFlags) const { return 0; }
2027 bool chmod(uint) { return false; }
2028 QString fileName(FileName) const { return name; }
2029 uint ownerId(FileOwner) const { return 0; }
2030 QString owner(FileOwner) const { return QString(); }
2031 QDateTime fileTime(FileTime) const { return QDateTime(); }
2038 class MyHandler : public QAbstractFileEngineHandler
2041 inline QAbstractFileEngine *create(const QString &) const
2043 return new MyEngine(1);
2047 class MyHandler2 : public QAbstractFileEngineHandler
2050 inline QAbstractFileEngine *create(const QString &) const
2052 return new MyEngine(2);
2057 void tst_QFile::fileEngineHandler()
2059 // A file that does not exist has a size of 0.
2060 QFile::remove("ole.bull");
2061 QFile file("ole.bull");
2062 QCOMPARE(file.size(), qint64(0));
2064 #ifdef QT_BUILD_INTERNAL
2065 // Instantiating our handler will enable the new engine.
2067 file.setFileName("ole.bull");
2068 QCOMPARE(file.size(), qint64(124));
2070 // A new, identical handler should take preference over the last one.
2071 MyHandler2 handler2;
2072 file.setFileName("ole.bull");
2073 QCOMPARE(file.size(), qint64(125));
2077 #ifdef QT_BUILD_INTERNAL
2078 class MyRecursiveHandler : public QAbstractFileEngineHandler
2081 inline QAbstractFileEngine *create(const QString &fileName) const
2083 if (fileName.startsWith(":!")) {
2085 QString realFile = QFINDTESTDATA(fileName.mid(2));
2086 if (dir.exists(realFile))
2087 return new QFSFileEngine(realFile);
2094 void tst_QFile::useQFileInAFileHandler()
2096 #ifdef QT_BUILD_INTERNAL
2097 // This test should not dead-lock
2098 MyRecursiveHandler handler;
2099 QFile file(":!tst_qfile.cpp");
2100 QVERIFY(file.exists());
2102 QSKIP("This test requires -developer-build.");
2106 void tst_QFile::getCharFF()
2108 QFile file("file.txt");
2109 file.open(QFile::ReadWrite);
2110 file.write("\xff\xff\xff");
2115 QVERIFY(file.getChar(&c));
2116 QVERIFY(file.getChar(&c));
2117 QVERIFY(file.getChar(&c));
2120 void tst_QFile::remove_and_exists()
2122 QFile::remove("tull_i_grunn.txt");
2123 QFile f("tull_i_grunn.txt");
2125 QVERIFY(!f.exists());
2127 bool opened = f.open(QIODevice::WriteOnly);
2130 f.write(QString("testing that remove/exists work...").toLatin1());
2133 QVERIFY(f.exists());
2136 QVERIFY(!f.exists());
2139 void tst_QFile::removeOpenFile()
2142 // remove an opened, write-only file
2143 QFile::remove("remove_unclosed.txt");
2144 QFile f("remove_unclosed.txt");
2146 QVERIFY(!f.exists());
2147 bool opened = f.open(QIODevice::WriteOnly);
2149 f.write(QString("testing that remove closes the file first...").toLatin1());
2151 bool removed = f.remove(); // remove should both close and remove the file
2153 QVERIFY(!f.isOpen());
2154 QVERIFY(!f.exists());
2155 QVERIFY(f.error() == QFile::NoError);
2159 // remove an opened, read-only file
2160 QFile::remove("remove_unclosed.txt");
2162 // first, write a file that we can remove
2164 QFile f("remove_unclosed.txt");
2165 QVERIFY(!f.exists());
2166 bool opened = f.open(QIODevice::WriteOnly);
2168 f.write(QString("testing that remove closes the file first...").toLatin1());
2172 QFile f("remove_unclosed.txt");
2173 bool opened = f.open(QIODevice::ReadOnly);
2176 // this used to only fail on FreeBSD (and Mac OS X)
2178 bool removed = f.remove(); // remove should both close and remove the file
2180 QVERIFY(!f.isOpen());
2181 QVERIFY(!f.exists());
2182 QVERIFY(f.error() == QFile::NoError);
2186 void tst_QFile::fullDisk()
2188 QFile file("/dev/full");
2190 QSKIP("/dev/full doesn't exist on this system");
2192 QVERIFY(file.open(QIODevice::WriteOnly));
2193 file.write("foobar", 6);
2195 QVERIFY(!file.flush());
2196 QCOMPARE(file.error(), QFile::ResourceError);
2197 QVERIFY(!file.flush());
2198 QCOMPARE(file.error(), QFile::ResourceError);
2202 QVERIFY(!file.flush());
2203 QCOMPARE(file.error(), QFile::ResourceError);
2204 QCOMPARE(file.write(&c, 1), qint64(1));
2205 QVERIFY(!file.flush());
2206 QCOMPARE(file.error(), QFile::ResourceError);
2209 QVERIFY(!file.isOpen());
2210 QCOMPARE(file.error(), QFile::ResourceError);
2212 file.open(QIODevice::WriteOnly);
2213 QCOMPARE(file.error(), QFile::NoError);
2214 QVERIFY(file.flush()); // Shouldn't inherit write buffer
2216 QCOMPARE(file.error(), QFile::NoError);
2218 // try again without flush:
2219 QVERIFY(file.open(QIODevice::WriteOnly));
2220 file.write("foobar", 6);
2222 QVERIFY(file.error() != QFile::NoError);
2225 void tst_QFile::writeLargeDataBlock_data()
2227 QTest::addColumn<QString>("fileName");
2228 QTest::addColumn<int>("type");
2230 QTest::newRow("localfile-QFile") << "./largeblockfile.txt" << (int)OpenQFile;
2231 QTest::newRow("localfile-Fd") << "./largeblockfile.txt" << (int)OpenFd;
2232 QTest::newRow("localfile-Stream") << "./largeblockfile.txt" << (int)OpenStream;
2234 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
2235 // Some semi-randomness to avoid collisions.
2236 QTest::newRow("unc file")
2237 << QString("//" + QtNetworkSettings::winServerName() + "/TESTSHAREWRITABLE/largefile-%1-%2.txt")
2238 .arg(QHostInfo::localHostName())
2239 .arg(QTime::currentTime().msec()) << (int)OpenQFile;
2243 static QByteArray getLargeDataBlock()
2245 static QByteArray array;
2249 #if defined(Q_OS_WINCE)
2250 int resizeSize = 1024 * 1024; // WinCE does not have much space
2252 int resizeSize = 64 * 1024 * 1024;
2254 array.resize(resizeSize);
2255 for (int i = 0; i < array.size(); ++i)
2256 array[i] = uchar(i);
2262 void tst_QFile::writeLargeDataBlock()
2264 QFETCH(QString, fileName);
2265 QFETCH( int, type );
2267 QByteArray const originalData = getLargeDataBlock();
2270 QFile file(fileName);
2272 QVERIFY2( openFile(file, QIODevice::WriteOnly, (FileType)type),
2273 qPrintable(QString("Couldn't open file for writing: [%1]").arg(fileName)) );
2274 qint64 fileWriteOriginalData = file.write(originalData);
2275 qint64 originalDataSize = (qint64)originalData.size();
2276 #if defined(Q_OS_WIN)
2277 if (fileWriteOriginalData == -1) {
2278 qWarning() << qPrintable(QString("Error writing a large data block to [%1]: %2")
2280 .arg(file.errorString()));
2281 QEXPECT_FAIL("unc file", "QTBUG-26906", Abort);
2284 QCOMPARE( fileWriteOriginalData, originalDataSize );
2285 QVERIFY( file.flush() );
2290 QByteArray readData;
2293 QFile file(fileName);
2295 QVERIFY2( openFile(file, QIODevice::ReadOnly, (FileType)type),
2296 qPrintable(QString("Couldn't open file for reading: [%1]").arg(fileName)) );
2297 readData = file.readAll();
2301 QCOMPARE( readData, originalData );
2302 QVERIFY( QFile::remove(fileName) );
2305 void tst_QFile::readFromWriteOnlyFile()
2307 QFile file("writeonlyfile");
2308 QVERIFY(file.open(QFile::WriteOnly));
2310 QTest::ignoreMessage(QtWarningMsg, "QIODevice::read: WriteOnly device");
2311 QCOMPARE(file.read(&c, 1), qint64(-1));
2314 void tst_QFile::writeToReadOnlyFile()
2316 QFile file("readonlyfile");
2317 QVERIFY(file.open(QFile::ReadOnly));
2319 QTest::ignoreMessage(QtWarningMsg, "QIODevice::write: ReadOnly device");
2320 QCOMPARE(file.write(&c, 1), qint64(-1));
2323 void tst_QFile::virtualFile()
2325 // test if QFile works with virtual files
2327 #if defined(Q_OS_LINUX)
2328 fname = "/proc/self/maps";
2329 #elif defined(Q_OS_AIX)
2330 fname = QString("/proc/%1/map").arg(getpid());
2331 #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
2332 fname = "/proc/curproc/map";
2334 QSKIP("This platform does not have 0-sized virtual files");
2337 // consistency check
2338 QFileInfo fi(fname);
2339 QVERIFY(fi.exists());
2340 QVERIFY(fi.isFile());
2341 QCOMPARE(fi.size(), Q_INT64_C(0));
2345 QVERIFY(f.open(QIODevice::ReadOnly));
2346 QCOMPARE(f.size(), Q_INT64_C(0));
2350 QByteArray data = f.read(16);
2351 QCOMPARE(data.size(), 16);
2352 QCOMPARE(f.pos(), Q_INT64_C(16));
2355 data = f.readLine();
2356 QVERIFY(!data.isEmpty());
2360 QVERIFY(f.pos() != 0);
2361 QVERIFY(!data.isEmpty());
2365 QCOMPARE(f.pos(), Q_INT64_C(1));
2368 void tst_QFile::textFile()
2370 #if defined(Q_OS_WINCE)
2371 FILE *fs = ::fopen((QCoreApplication::applicationDirPath() + "/writeabletextfile").toLatin1() , "wt");
2372 #elif defined(Q_OS_WIN)
2373 FILE *fs = ::fopen("writeabletextfile", "wt");
2375 FILE *fs = ::fopen("writeabletextfile", "w");
2378 QByteArray part1("This\nis\na\nfile\nwith\nnewlines\n");
2379 QByteArray part2("Add\nsome\nmore\nnewlines\n");
2381 QVERIFY(f.open(fs, QIODevice::WriteOnly));
2387 QFile file("writeabletextfile");
2388 QVERIFY(file.open(QIODevice::ReadOnly));
2390 QByteArray data = file.readAll();
2392 QByteArray expected = part1 + part2;
2394 expected.replace("\n", "\015\012");
2396 QCOMPARE(data, expected);
2401 void tst_QFile::rename_data()
2403 QTest::addColumn<QString>("source");
2404 QTest::addColumn<QString>("destination");
2405 QTest::addColumn<bool>("result");
2407 QTest::newRow("a -> b") << QString("a") << QString("b") << false;
2408 QTest::newRow("a -> .") << QString("a") << QString(".") << false;
2409 QTest::newRow("renamefile -> renamefile") << QString("renamefile") << QString("renamefile") << false;
2410 QTest::newRow("renamefile -> noreadfile") << QString("renamefile") << QString("noreadfile") << false;
2411 #if defined(Q_OS_UNIX)
2412 QTest::newRow("renamefile -> /etc/renamefile") << QString("renamefile") << QString("/etc/renamefile") << false;
2414 QTest::newRow("renamefile -> renamedfile") << QString("renamefile") << QString("renamedfile") << true;
2415 QTest::newRow("renamefile -> ..") << QString("renamefile") << QString("..") << false;
2418 void tst_QFile::rename()
2420 QFETCH(QString, source);
2421 QFETCH(QString, destination);
2422 QFETCH(bool, result);
2424 #if defined(Q_OS_UNIX)
2425 if (strcmp(QTest::currentDataTag(), "renamefile -> /etc/renamefile") == 0) {
2426 if (::getuid() == 0)
2427 QSKIP("Running this test as root doesn't make sense");
2431 QFile::remove("renamedfile");
2432 QFile f("renamefile");
2433 f.open(QFile::WriteOnly);
2437 QCOMPARE(file.rename(destination), result);
2440 QCOMPARE(file.error(), QFile::NoError);
2442 QCOMPARE(file.error(), QFile::RenameError);
2444 QFile::remove("renamefile");
2450 Some special files have QFile::atEnd() returning true, even though there is
2451 more data available. True for corner cases, as well as some mounts on OS X.
2453 Here, we reproduce that condition by having a QFile sub-class with this
2454 peculiar atEnd() behavior.
2456 void tst_QFile::renameWithAtEndSpecialFile() const
2458 class PeculiarAtEnd : public QFile
2461 virtual bool atEnd() const
2467 const QString newName(QLatin1String("newName.txt"));
2468 /* Cleanup, so we're a bit more robust. */
2469 QFile::remove(newName);
2471 const QString originalName(QString(QFINDTESTDATA("forRenaming.txt")));
2474 file.setFileName(originalName);
2475 QVERIFY(file.open(QIODevice::ReadOnly));
2477 QVERIFY(file.rename(newName));
2480 /* Guess what, we have to rename it back, otherwise we'll fail on second
2482 QVERIFY(QFile::rename(newName, originalName));
2485 void tst_QFile::renameFallback()
2487 // Using a resource file both to trigger QFile::rename's fallback handling
2488 // and as a *read-only* source whose move should fail.
2489 QFile file(":/rename-fallback.qrc");
2490 QVERIFY(file.exists() && "(test-precondition)");
2491 QFile::remove("file-rename-destination.txt");
2493 QVERIFY(!file.rename("file-rename-destination.txt"));
2494 QVERIFY(!QFile::exists("file-rename-destination.txt"));
2495 QVERIFY(!file.isOpen());
2498 void tst_QFile::renameMultiple()
2500 // create the file if it doesn't exist
2501 QFile file("file-to-be-renamed.txt");
2502 QFile file2("existing-file.txt");
2503 QVERIFY(file.open(QIODevice::ReadWrite) && "(test-precondition)");
2504 QVERIFY(file2.open(QIODevice::ReadWrite) && "(test-precondition)");
2506 // any stale files from previous test failures?
2507 QFile::remove("file-renamed-once.txt");
2508 QFile::remove("file-renamed-twice.txt");
2511 QVERIFY(QFile::exists("existing-file.txt"));
2512 QVERIFY(!file.rename("existing-file.txt"));
2513 QCOMPARE(file.error(), QFile::RenameError);
2514 QCOMPARE(file.fileName(), QString("file-to-be-renamed.txt"));
2516 QVERIFY(file.rename("file-renamed-once.txt"));
2517 QVERIFY(!file.isOpen());
2518 QCOMPARE(file.fileName(), QString("file-renamed-once.txt"));
2520 QVERIFY(QFile::exists("existing-file.txt"));
2521 QVERIFY(!file.rename("existing-file.txt"));
2522 QCOMPARE(file.error(), QFile::RenameError);
2523 QCOMPARE(file.fileName(), QString("file-renamed-once.txt"));
2525 QVERIFY(file.rename("file-renamed-twice.txt"));
2526 QVERIFY(!file.isOpen());
2527 QCOMPARE(file.fileName(), QString("file-renamed-twice.txt"));
2529 QVERIFY(QFile::exists("existing-file.txt"));
2530 QVERIFY(!QFile::exists("file-to-be-renamed.txt"));
2531 QVERIFY(!QFile::exists("file-renamed-once.txt"));
2532 QVERIFY(QFile::exists("file-renamed-twice.txt"));
2536 QVERIFY(!QFile::exists("file-renamed-twice.txt"));
2537 QVERIFY(!QFile::exists("existing-file.txt"));
2540 void tst_QFile::appendAndRead()
2542 QFile writeFile(QLatin1String("appendfile.txt"));
2543 QVERIFY(writeFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
2545 QFile readFile(QLatin1String("appendfile.txt"));
2546 QVERIFY(readFile.open(QIODevice::ReadOnly));
2548 // Write to the end of the file, then read that character back, and so on.
2549 for (int i = 0; i < 100; ++i) {
2551 writeFile.putChar(char(i % 256));
2553 QVERIFY(readFile.getChar(&c));
2554 QCOMPARE(c, char(i % 256));
2555 QCOMPARE(readFile.pos(), writeFile.pos());
2558 // Write blocks and read them back
2559 for (int j = 0; j < 18; ++j) {
2560 writeFile.write(QByteArray(1 << j, '@'));
2562 QCOMPARE(readFile.read(1 << j).size(), 1 << j);
2566 QFile::remove(QLatin1String("appendfile.txt"));
2569 void tst_QFile::miscWithUncPathAsCurrentDir()
2571 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
2572 QString current = QDir::currentPath();
2573 QVERIFY(QDir::setCurrent("//" + QtNetworkSettings::winServerName() + "/testshare"));
2574 QFile file("test.pri");
2575 QVERIFY(file.exists());
2576 QCOMPARE(int(file.size()), 34);
2577 QVERIFY(file.open(QIODevice::ReadOnly));
2578 QVERIFY(QDir::setCurrent(current));
2582 void tst_QFile::standarderror()
2585 bool ok = f.open(stderr, QFile::WriteOnly);
2590 void tst_QFile::handle()
2593 #if !defined(Q_OS_WINCE)
2594 QFile file(QFINDTESTDATA("tst_qfile.cpp"));
2595 QVERIFY(file.open(QIODevice::ReadOnly));
2596 fd = int(file.handle());
2598 QCOMPARE(int(file.handle()), fd);
2600 QT_READ(int(file.handle()), &c, 1);
2603 // test if the QFile and the handle remain in sync
2604 QVERIFY(file.getChar(&c));
2607 // same, but read from QFile first now
2609 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Unbuffered));
2610 fd = int(file.handle());
2612 QVERIFY(file.getChar(&c));
2615 QCOMPARE(QT_READ(fd, &c, 1), ssize_t(1));
2617 QCOMPARE(QT_READ(fd, &c, 1), 1);
2623 //test round trip of adopted stdio file handle
2625 FILE *fp = fopen(qPrintable(QFINDTESTDATA("tst_qfile.cpp")), "r");
2626 file2.open(fp, QIODevice::ReadOnly);
2627 QCOMPARE(int(file2.handle()), int(fileno(fp)));
2628 QCOMPARE(int(file2.handle()), int(fileno(fp)));
2631 //test round trip of adopted posix file handle
2634 fd = QT_OPEN(qPrintable(QFINDTESTDATA("tst_qfile.cpp")), QT_OPEN_RDONLY);
2635 file3.open(fd, QIODevice::ReadOnly);
2636 QCOMPARE(int(file3.handle()), fd);
2641 void tst_QFile::nativeHandleLeaks()
2646 HANDLE handle1, handle2;
2650 QFile file("qt_file.tmp");
2651 QVERIFY( file.open(QIODevice::ReadWrite) );
2653 fd1 = file.handle();
2654 QVERIFY( -1 != fd1 );
2658 handle1 = ::CreateFileA("qt_file.tmp", GENERIC_READ, 0, NULL,
2659 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2660 QVERIFY( INVALID_HANDLE_VALUE != handle1 );
2661 QVERIFY( ::CloseHandle(handle1) );
2665 QFile file("qt_file.tmp");
2666 QVERIFY( file.open(QIODevice::ReadOnly) );
2668 fd2 = file.handle();
2669 QVERIFY( -1 != fd2 );
2673 handle2 = ::CreateFileA("qt_file.tmp", GENERIC_READ, 0, NULL,
2674 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2675 QVERIFY( INVALID_HANDLE_VALUE != handle2 );
2676 QVERIFY( ::CloseHandle(handle2) );
2679 QCOMPARE( fd2, fd1 );
2682 QCOMPARE( handle2, handle1 );
2686 void tst_QFile::readEof_data()
2688 QTest::addColumn<QString>("filename");
2689 QTest::addColumn<int>("imode");
2691 QTest::newRow("buffered") << QFINDTESTDATA("testfile.txt") << 0;
2692 QTest::newRow("unbuffered") << QFINDTESTDATA("testfile.txt") << int(QIODevice::Unbuffered);
2694 #if defined(Q_OS_UNIX)
2695 QTest::newRow("sequential,buffered") << "/dev/null" << 0;
2696 QTest::newRow("sequential,unbuffered") << "/dev/null" << int(QIODevice::Unbuffered);
2700 void tst_QFile::readEof()
2702 QFETCH(QString, filename);
2704 QIODevice::OpenMode mode = QIODevice::OpenMode(imode);
2707 QFile file(filename);
2708 QVERIFY(file.open(QIODevice::ReadOnly | mode));
2709 bool isSequential = file.isSequential();
2710 if (!isSequential) {
2711 QVERIFY(file.seek(245));
2712 QVERIFY(file.atEnd());
2716 int ret = file.read(buf, sizeof buf);
2718 QVERIFY(file.error() == QFile::NoError);
2719 QVERIFY(file.atEnd());
2721 // Do it again to ensure that we get the same result
2722 ret = file.read(buf, sizeof buf);
2724 QVERIFY(file.error() == QFile::NoError);
2725 QVERIFY(file.atEnd());
2729 QFile file(filename);
2730 QVERIFY(file.open(QIODevice::ReadOnly | mode));
2731 bool isSequential = file.isSequential();
2732 if (!isSequential) {
2733 QVERIFY(file.seek(245));
2734 QVERIFY(file.atEnd());
2737 QByteArray ret = file.read(10);
2738 QVERIFY(ret.isEmpty());
2739 QVERIFY(file.error() == QFile::NoError);
2740 QVERIFY(file.atEnd());
2742 // Do it again to ensure that we get the same result
2743 ret = file.read(10);
2744 QVERIFY(ret.isEmpty());
2745 QVERIFY(file.error() == QFile::NoError);
2746 QVERIFY(file.atEnd());
2750 QFile file(filename);
2751 QVERIFY(file.open(QIODevice::ReadOnly | mode));
2752 bool isSequential = file.isSequential();
2753 if (!isSequential) {
2754 QVERIFY(file.seek(245));
2755 QVERIFY(file.atEnd());
2759 int ret = file.readLine(buf, sizeof buf);
2761 QVERIFY(file.error() == QFile::NoError);
2762 QVERIFY(file.atEnd());
2764 // Do it again to ensure that we get the same result
2765 ret = file.readLine(buf, sizeof buf);
2767 QVERIFY(file.error() == QFile::NoError);
2768 QVERIFY(file.atEnd());
2772 QFile file(filename);
2773 QVERIFY(file.open(QIODevice::ReadOnly | mode));
2774 bool isSequential = file.isSequential();
2775 if (!isSequential) {
2776 QVERIFY(file.seek(245));
2777 QVERIFY(file.atEnd());
2780 QByteArray ret = file.readLine();
2781 QVERIFY(ret.isNull());
2782 QVERIFY(file.error() == QFile::NoError);
2783 QVERIFY(file.atEnd());
2785 // Do it again to ensure that we get the same result
2786 ret = file.readLine();
2787 QVERIFY(ret.isNull());
2788 QVERIFY(file.error() == QFile::NoError);
2789 QVERIFY(file.atEnd());
2793 QFile file(filename);
2794 QVERIFY(file.open(QIODevice::ReadOnly | mode));
2795 bool isSequential = file.isSequential();
2796 if (!isSequential) {
2797 QVERIFY(file.seek(245));
2798 QVERIFY(file.atEnd());
2802 QVERIFY(!file.getChar(&c));
2803 QVERIFY(file.error() == QFile::NoError);
2804 QVERIFY(file.atEnd());
2806 // Do it again to ensure that we get the same result
2807 QVERIFY(!file.getChar(&c));
2808 QVERIFY(file.error() == QFile::NoError);
2809 QVERIFY(file.atEnd());
2813 void tst_QFile::posAfterFailedStat()
2815 // Regression test for a bug introduced in 4.3.0; after a failed stat,
2816 // pos() could no longer be calculated correctly.
2817 QFile::remove("tmp.txt");
2818 QFile file("tmp.txt");
2819 QVERIFY(!file.exists());
2820 QVERIFY(file.open(QIODevice::Append));
2821 QVERIFY(file.exists());
2822 file.write("qt430", 5);
2823 QVERIFY(!file.isSequential());
2824 QCOMPARE(file.pos(), qint64(5));
2828 #define FILESIZE 65536 * 3
2830 void tst_QFile::map_data()
2832 QTest::addColumn<int>("fileSize");
2833 QTest::addColumn<int>("offset");
2834 QTest::addColumn<int>("size");
2835 QTest::addColumn<QFile::FileError>("error");
2837 QTest::newRow("zero") << FILESIZE << 0 << FILESIZE << QFile::NoError;
2838 QTest::newRow("small, but 0") << FILESIZE << 30 << FILESIZE - 30 << QFile::NoError;
2839 QTest::newRow("a page") << FILESIZE << 4096 << FILESIZE - 4096 << QFile::NoError;
2840 QTest::newRow("+page") << FILESIZE << 5000 << FILESIZE - 5000 << QFile::NoError;
2841 QTest::newRow("++page") << FILESIZE << 65576 << FILESIZE - 65576 << QFile::NoError;
2842 QTest::newRow("bad size") << FILESIZE << 0 << -1 << QFile::ResourceError;
2843 QTest::newRow("bad offset") << FILESIZE << -1 << 1 << QFile::UnspecifiedError;
2844 QTest::newRow("zerozero") << FILESIZE << 0 << 0 << QFile::UnspecifiedError;
2847 void tst_QFile::map()
2849 QFETCH(int, fileSize);
2850 QFETCH(int, offset);
2852 QFETCH(QFile::FileError, error);
2854 QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile";
2857 fileName = QFileInfo(fileName).absoluteFilePath();
2860 if (QFile::exists(fileName)) {
2861 QVERIFY(QFile::setPermissions(fileName,
2862 QFile::WriteOwner | QFile::ReadOwner | QFile::WriteUser | QFile::ReadUser));
2863 QFile::remove(fileName);
2865 QFile file(fileName);
2867 // invalid, not open
2868 uchar *memory = file.map(0, size);
2870 QCOMPARE(file.error(), QFile::PermissionsError);
2871 QVERIFY(!file.unmap(memory));
2872 QCOMPARE(file.error(), QFile::PermissionsError);
2875 QVERIFY(file.open(QFile::ReadWrite));
2876 QVERIFY(file.resize(fileSize));
2877 QVERIFY(file.flush());
2879 QVERIFY(file.open(QFile::ReadWrite));
2880 memory = file.map(offset, size);
2881 if (error != QFile::NoError) {
2882 QVERIFY(file.error() != QFile::NoError);
2886 QCOMPARE(file.error(), error);
2889 QVERIFY(file.unmap(memory));
2890 QCOMPARE(file.error(), QFile::NoError);
2892 // Verify changes were saved
2893 memory = file.map(offset, size);
2894 QCOMPARE(file.error(), QFile::NoError);
2896 QVERIFY(memory[0] == 'Q');
2897 QVERIFY(file.unmap(memory));
2898 QCOMPARE(file.error(), QFile::NoError);
2900 // hpux wont let you map multiple times.
2901 #if !defined(Q_OS_HPUX) && !defined(Q_USE_DEPRECATED_MAP_API) && !defined(Q_OS_WINCE)
2902 // exotic test to make sure that multiple maps work
2904 // note: windows ce does not reference count mutliple maps
2905 // it's essentially just the same reference but it
2906 // cause a resource lock on the file which prevents it
2907 // from being removed uchar *memory1 = file.map(0, file.size());
2908 uchar *memory1 = file.map(0, file.size());
2909 QCOMPARE(file.error(), QFile::NoError);
2910 uchar *memory2 = file.map(0, file.size());
2911 QCOMPARE(file.error(), QFile::NoError);
2914 QVERIFY(file.unmap(memory1));
2915 QCOMPARE(file.error(), QFile::NoError);
2916 QVERIFY(file.unmap(memory2));
2917 QCOMPARE(file.error(), QFile::NoError);
2918 memory1 = file.map(0, file.size());
2919 QCOMPARE(file.error(), QFile::NoError);
2921 QVERIFY(file.unmap(memory1));
2922 QCOMPARE(file.error(), QFile::NoError);
2927 #if defined(Q_OS_UNIX)
2928 if (::getuid() != 0)
2929 // root always has permissions
2932 // Change permissions on a file, just to confirm it would fail
2933 QFile::Permissions originalPermissions = file.permissions();
2934 QVERIFY(file.setPermissions(QFile::ReadOther));
2935 QVERIFY(!file.open(QFile::ReadWrite));
2936 memory = file.map(offset, size);
2937 QCOMPARE(file.error(), QFile::PermissionsError);
2939 QVERIFY(file.setPermissions(originalPermissions));
2941 QVERIFY(file.remove());
2944 void tst_QFile::mapResource_data()
2946 QTest::addColumn<int>("offset");
2947 QTest::addColumn<int>("size");
2948 QTest::addColumn<QFile::FileError>("error");
2949 QTest::addColumn<QString>("fileName");
2951 QString validFile = ":/tst_qfileinfo/resources/file1.ext1";
2952 QString invalidFile = ":/tst_qfileinfo/resources/filefoo.ext1";
2954 for (int i = 0; i < 2; ++i) {
2955 QString file = (i == 0) ? validFile : invalidFile;
2956 QTest::newRow("0, 0") << 0 << 0 << QFile::UnspecifiedError << file;
2957 QTest::newRow("0, BIG") << 0 << 4096 << QFile::UnspecifiedError << file;
2958 QTest::newRow("-1, 0") << -1 << 0 << QFile::UnspecifiedError << file;
2959 QTest::newRow("0, -1") << 0 << -1 << QFile::UnspecifiedError << file;
2962 QTest::newRow("0, 1") << 0 << 1 << QFile::NoError << validFile;
2965 void tst_QFile::mapResource()
2967 QFETCH(QString, fileName);
2968 QFETCH(int, offset);
2970 QFETCH(QFile::FileError, error);
2972 QFile file(fileName);
2973 uchar *memory = file.map(offset, size);
2974 QCOMPARE(file.error(), error);
2975 QVERIFY((error == QFile::NoError) ? (memory != 0) : (memory == 0));
2976 if (error == QFile::NoError)
2977 QCOMPARE(QString(memory[0]), QString::number(offset + 1));
2978 QVERIFY(file.unmap(memory));
2981 void tst_QFile::mapOpenMode_data()
2983 QTest::addColumn<int>("openMode");
2985 QTest::newRow("ReadOnly") << int(QIODevice::ReadOnly);
2986 //QTest::newRow("WriteOnly") << int(QIODevice::WriteOnly); // this doesn't make sense
2987 QTest::newRow("ReadWrite") << int(QIODevice::ReadWrite);
2988 QTest::newRow("ReadOnly,Unbuffered") << int(QIODevice::ReadOnly | QIODevice::Unbuffered);
2989 QTest::newRow("ReadWrite,Unbuffered") << int(QIODevice::ReadWrite | QIODevice::Unbuffered);
2992 void tst_QFile::mapOpenMode()
2994 QFETCH(int, openMode);
2995 static const qint64 fileSize = 4096;
2997 QByteArray pattern(fileSize, 'A');
2999 QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile";
3000 if (QFile::exists(fileName)) {
3001 QVERIFY(QFile::setPermissions(fileName,
3002 QFile::WriteOwner | QFile::ReadOwner | QFile::WriteUser | QFile::ReadUser));
3003 QFile::remove(fileName);
3005 QFile file(fileName);
3008 QVERIFY(file.open(QFile::ReadWrite));
3009 QVERIFY(file.write(pattern));
3010 QVERIFY(file.flush());
3013 // open according to our mode
3014 QVERIFY(file.open(QIODevice::OpenMode(openMode)));
3016 uchar *memory = file.map(0, fileSize);
3018 QVERIFY(memcmp(memory, pattern, fileSize) == 0);
3020 if (openMode & QIODevice::WriteOnly) {
3021 // try to write to the file
3025 file.open(QIODevice::OpenMode(openMode));
3028 QVERIFY(file.getChar(&c));
3035 void tst_QFile::openDirectory()
3037 QFile f1(QFINDTESTDATA("resources"));
3038 // it's a directory, it must exist
3039 QVERIFY(f1.exists());
3041 // ...but not be openable
3042 QVERIFY(!f1.open(QIODevice::ReadOnly));
3044 QVERIFY(!f1.open(QIODevice::ReadOnly|QIODevice::Unbuffered));
3046 QVERIFY(!f1.open(QIODevice::ReadWrite));
3048 QVERIFY(!f1.open(QIODevice::WriteOnly));
3050 QVERIFY(!f1.open(QIODevice::WriteOnly|QIODevice::Unbuffered));
3054 static qint64 streamExpectedSize(int fd)
3057 if (QT_FSTAT(fd, &sb) != -1)
3062 static qint64 streamCurrentPosition(int fd)
3064 QT_OFF_T pos = QT_LSEEK(fd, 0, SEEK_CUR);
3070 static qint64 streamCurrentPosition(FILE *f)
3072 QT_OFF_T pos = QT_FTELL(f);
3078 class MessageHandler {
3080 MessageHandler(QtMessageHandler messageHandler = handler)
3083 oldMessageHandler = qInstallMessageHandler(messageHandler);
3088 qInstallMessageHandler(oldMessageHandler);
3091 static bool testPassed()
3096 static void handler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
3098 if (msg == QString::fromLatin1("QIODevice::seek: Cannot call seek on a sequential device"))
3100 // Defer to old message handler.
3101 if (oldMessageHandler)
3102 oldMessageHandler(type, context, msg);
3105 static QtMessageHandler oldMessageHandler;
3109 bool MessageHandler::ok = true;
3110 QtMessageHandler MessageHandler::oldMessageHandler = 0;
3112 void tst_QFile::openStandardStreamsFileDescriptors()
3115 //allthough Windows CE (not mobile!) has functions that allow redirecting
3116 //the standard file descriptors to a file (see SetStdioPathW/GetStdioPathW)
3117 //it does not have functions to simply open them like below .
3118 QSKIP("Opening standard streams on Windows CE via descriptor not implemented");
3121 // Check that QIODevice::seek() isn't called when opening a sequential device (QFile).
3122 MessageHandler msgHandler;
3126 in.open(STDIN_FILENO, QIODevice::ReadOnly);
3127 QCOMPARE( in.pos(), streamCurrentPosition(STDIN_FILENO) );
3128 QCOMPARE( in.size(), streamExpectedSize(STDIN_FILENO) );
3133 QVERIFY(out.open(STDOUT_FILENO, QIODevice::WriteOnly));
3134 QCOMPARE( out.pos(), streamCurrentPosition(STDOUT_FILENO) );
3135 QCOMPARE( out.size(), streamExpectedSize(STDOUT_FILENO) );
3140 err.open(STDERR_FILENO, QIODevice::WriteOnly);
3141 QCOMPARE( err.pos(), streamCurrentPosition(STDERR_FILENO) );
3142 QCOMPARE( err.size(), streamExpectedSize(STDERR_FILENO) );
3145 QVERIFY(msgHandler.testPassed());
3148 void tst_QFile::openStandardStreamsBufferedStreams()
3151 QSKIP("Not tested on Windows CE.");
3153 // Check that QIODevice::seek() isn't called when opening a sequential device (QFile).
3154 MessageHandler msgHandler;
3159 in.open(stdin, QIODevice::ReadOnly);
3160 QCOMPARE( in.pos(), streamCurrentPosition(stdin) );
3161 QCOMPARE( in.size(), streamExpectedSize(QT_FILENO(stdin)) );
3166 out.open(stdout, QIODevice::WriteOnly);
3167 QCOMPARE( out.pos(), streamCurrentPosition(stdout) );
3168 QCOMPARE( out.size(), streamExpectedSize(QT_FILENO(stdout)) );
3173 err.open(stderr, QIODevice::WriteOnly);
3174 QCOMPARE( err.pos(), streamCurrentPosition(stderr) );
3175 QCOMPARE( err.size(), streamExpectedSize(QT_FILENO(stderr)) );
3178 QVERIFY(msgHandler.testPassed());
3181 void tst_QFile::writeNothing()
3183 for (int i = 0; i < NumberOfFileTypes; ++i) {
3184 QFile file("file.txt");
3185 QVERIFY( openFile(file, QIODevice::WriteOnly | QIODevice::Unbuffered, FileType(i)) );
3186 QVERIFY( 0 == file.write((char *)0, 0) );
3187 QCOMPARE( file.error(), QFile::NoError );
3192 void tst_QFile::resize_data()
3194 QTest::addColumn<int>("filetype");
3196 QTest::newRow("native") << int(OpenQFile);
3197 QTest::newRow("fileno") << int(OpenFd);
3198 QTest::newRow("stream") << int(OpenStream);
3201 void tst_QFile::resize()
3203 QFETCH(int, filetype);
3204 QString filename(QLatin1String("file.txt"));
3205 QFile file(filename);
3206 QVERIFY(openFile(file, QIODevice::ReadWrite, FileType(filetype)));
3207 QVERIFY(file.resize(8));
3208 QCOMPARE(file.size(), qint64(8));
3210 QFile::resize(filename, 4);
3211 QCOMPARE(QFileInfo(filename).size(), qint64(4));
3212 QVERIFY(QFile::remove(filename));
3215 void tst_QFile::objectConstructors()
3218 QFile* file1 = new QFile(QFINDTESTDATA("testfile.txt"), &ob);
3219 QFile* file2 = new QFile(&ob);
3220 QVERIFY(file1->exists());
3221 QVERIFY(!file2->exists());
3224 void tst_QFile::caseSensitivity()
3226 #if defined(Q_OS_WIN) || defined(Q_OS_MAC)
3227 const bool caseSensitive = false;
3229 const bool caseSensitive = true;
3231 QByteArray testData("a little test");
3232 QString filename("File.txt");
3235 QVERIFY(f.open(QIODevice::WriteOnly));
3236 QVERIFY(f.write(testData));
3239 QStringList alternates;
3240 QFileInfo fi(filename);
3241 QVERIFY(fi.exists());
3242 alternates << "file.txt" << "File.TXT" << "fIlE.TxT" << fi.absoluteFilePath().toUpper() << fi.absoluteFilePath().toLower();
3243 foreach (QString alt, alternates) {
3245 QCOMPARE(fi2.exists(), !caseSensitive);
3246 QCOMPARE(fi.size() == fi2.size(), !caseSensitive);
3248 QCOMPARE(f2.open(QIODevice::ReadOnly), !caseSensitive);
3250 QCOMPARE(f2.readAll(), testData);
3254 //MSVCRT asserts when any function is called with a closed file handle.
3255 //This replaces the default crashing error handler with one that ignores the error (allowing EBADF to be returned)
3256 class AutoIgnoreInvalidParameter
3259 #if defined(Q_OS_WIN) && defined (Q_CC_MSVC)
3260 static void ignore_invalid_parameter(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, uintptr_t) {}
3261 AutoIgnoreInvalidParameter()
3263 oldHandler = _set_invalid_parameter_handler(ignore_invalid_parameter);
3264 //also disable the abort/retry/ignore popup
3265 oldReportMode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
3267 ~AutoIgnoreInvalidParameter()
3269 //restore previous settings
3270 _set_invalid_parameter_handler(oldHandler);
3271 _CrtSetReportMode(_CRT_ASSERT, oldReportMode);
3273 _invalid_parameter_handler oldHandler;
3278 void tst_QFile::autocloseHandle()
3281 QFile file("readonlyfile");
3282 QVERIFY(openFile(file, QIODevice::ReadOnly, OpenFd, QFile::AutoCloseHandle));
3284 QCOMPARE(file.handle(), fd);
3287 QCOMPARE(file.handle(), -1);
3288 AutoIgnoreInvalidParameter a;
3290 //file is closed, read should fail
3292 QCOMPARE((int)QT_READ(fd, &buf, 1), -1);
3293 QVERIFY(errno = EBADF);
3297 QFile file("readonlyfile");
3298 QVERIFY(openFile(file, QIODevice::ReadOnly, OpenFd, QFile::DontCloseHandle));
3299 QCOMPARE(file.handle(), fd_);
3301 QCOMPARE(file.handle(), -1);
3302 //file is not closed, read should succeed
3304 QCOMPARE((int)QT_READ(fd_, &buf, 1), 1);
3310 QFile file("readonlyfile");
3311 QVERIFY(openFile(file, QIODevice::ReadOnly, OpenStream, QFile::AutoCloseHandle));
3312 int fd = QT_FILENO(stream_);
3313 QCOMPARE(file.handle(), fd);
3316 QCOMPARE(file.handle(), -1);
3317 AutoIgnoreInvalidParameter a;
3319 //file is closed, read should fail
3321 QCOMPARE((int)QT_READ(fd, &buf, 1), -1); //not using fread because the FILE* was freed by fclose
3325 QFile file("readonlyfile");
3326 QVERIFY(openFile(file, QIODevice::ReadOnly, OpenStream, QFile::DontCloseHandle));
3327 QCOMPARE(file.handle(), QT_FILENO(stream_));
3329 QCOMPARE(file.handle(), -1);
3330 //file is not closed, read should succeed
3332 QCOMPARE(int(::fread(&buf, 1, 1, stream_)), 1);
3338 QTEST_MAIN(tst_QFile)
3339 #include "tst_qfile.moc"