summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2018-07-23 20:06:04 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2018-07-30 15:04:31 +0000
commitcb505bedde4940d927b593ecc3668789e9f1c0a0 (patch)
tree47a002a0519d728491a354af340a4c5b831c7464
parent5da8e5ddd424a11435a3750dc9b955295aeaed9c (diff)
Actually truncate when asked to
On Unix, we wouldn't even *try* to truncate if the file was open for appending. The combination may be an eccentric choice but - at least when it's combined with reading - I can imagine use-cases for it; and we should (at least try to) deliver what we're asked for, even if we can't think why anyone would want it. So actually enable truncation when asked to. Amended some tests to check this works and corrected the QIODevice documentation of mode flags (which misdescribed the special case that implies Truncate). Removed special-case code, to apply truncate when writing but not reading, since it's been made redundant by the pre-processing of mode done in QFSFileEngine::processOpenModeFlags(). [ChangeLog][QtCore][QFile] When opening a file, if Truncate is asked for, or implied by other flags, it shall be attempted, regardless of what other options are selected. We previously did this on Windows; now we do so also on Unix (even when appending). Task-number: QTBUG-13470 Change-Id: I1e08d02cfbae102725fccbbc3aab5c7bf8830687 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp9
-rw-r--r--src/corelib/io/qiodevice.cpp5
-rw-r--r--tests/auto/corelib/io/qfile/tst_qfile.cpp13
3 files changed, 17 insertions, 10 deletions
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index bc39ea73ee..b82415cb26 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -82,12 +82,11 @@ static inline int openModeToOpenFlags(QIODevice::OpenMode mode)
if (QFSFileEnginePrivate::openModeCanCreate(mode))
oflags |= QT_OPEN_CREAT;
- if (mode & QFile::Append) {
+ if (mode & QFile::Truncate)
+ oflags |= QT_OPEN_TRUNC;
+
+ if (mode & QFile::Append)
oflags |= QT_OPEN_APPEND;
- } else if (mode & QFile::WriteOnly) {
- if ((mode & QFile::Truncate) || !(mode & QFile::ReadOnly))
- oflags |= QT_OPEN_TRUNC;
- }
if (mode & QFile::NewOnly)
oflags |= QT_OPEN_EXCL;
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 95a5fb27cf..5dd5f8031e 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -312,8 +312,9 @@ QIODevicePrivate::~QIODevicePrivate()
\value NotOpen The device is not open.
\value ReadOnly The device is open for reading.
- \value WriteOnly The device is open for writing. Note that this mode implies
- Truncate.
+ \value WriteOnly The device is open for writing. Note that, for file-system
+ subclasses (e.g. QFile), this mode implies Truncate unless
+ combined with ReadOnly, Append or NewOnly.
\value ReadWrite The device is open for reading and writing.
\value Append The device is opened in append mode so that all data is
written to the end of the file.
diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp
index de4dbfc2a9..2d01dbb90a 100644
--- a/tests/auto/corelib/io/qfile/tst_qfile.cpp
+++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp
@@ -1293,6 +1293,12 @@ void tst_QFile::append()
f.putChar('a');
f.close();
QCOMPARE(int(f.size()), 2);
+
+ QVERIFY2(f.open(QIODevice::Append | QIODevice::Truncate), msgOpenFailed(f).constData());
+ QCOMPARE(f.pos(), 0);
+ f.putChar('a');
+ f.close();
+ QCOMPARE(int(f.size()), 1);
}
void tst_QFile::permissions_data()
@@ -1829,13 +1835,14 @@ void tst_QFile::encodeName()
void tst_QFile::truncate()
{
- for (int i = 0; i < 2; ++i) {
+ const QIODevice::OpenModeFlag modes[] = { QFile::ReadWrite, QIODevice::WriteOnly, QIODevice::Append };
+ for (auto mode : modes) {
QFile file("truncate.txt");
QVERIFY2(file.open(QFile::WriteOnly), msgOpenFailed(file).constData());
file.write(QByteArray(200, '@'));
file.close();
- QVERIFY2(file.open((i ? QFile::WriteOnly : QFile::ReadWrite) | QFile::Truncate), msgOpenFailed(file).constData());
+ QVERIFY2(file.open(mode | QFile::Truncate), msgOpenFailed(file).constData());
file.write(QByteArray(100, '$'));
file.close();
@@ -2753,7 +2760,7 @@ void tst_QFile::renameMultiple()
void tst_QFile::appendAndRead()
{
QFile writeFile(QLatin1String("appendfile.txt"));
- QVERIFY2(writeFile.open(QIODevice::WriteOnly | QIODevice::Truncate), msgOpenFailed(writeFile).constData());
+ QVERIFY2(writeFile.open(QIODevice::Append | QIODevice::Truncate), msgOpenFailed(writeFile).constData());
QFile readFile(QLatin1String("appendfile.txt"));
QVERIFY2(readFile.open(QIODevice::ReadOnly), msgOpenFailed(readFile).constData());