diff --git a/autotests/jobtest.cpp b/autotests/jobtest.cpp --- a/autotests/jobtest.cpp +++ b/autotests/jobtest.cpp @@ -2140,15 +2140,14 @@ const QString srcTemplate = baseDir + QStringLiteral("testfile_XXXXXX"); const QString destFile = baseDir + QStringLiteral("testfile_copy"); - QTemporaryFile f(srcTemplate); if (!f.open()) { qFatal("Couldn't open %s", qPrintable(f.fileName())); } - f.seek(9999999); + f.seek(49999999); f.write("0"); f.close(); - QCOMPARE(f.size(), 10000000); //~10MB + QCOMPARE(f.size(), 50000000); //~50MB to make sure copy is not too fast, or the no_overwrite cases will fail if (overwrite) { createTestFile(destFile); @@ -2160,20 +2159,24 @@ QSignalSpy spyProcessedSize(copyJob, &KIO::Job::processedSize); connect(copyJob, &KIO::Job::processedSize, this, [destFile, suspend, overwrite](KJob *job, qulonglong processedSize) { if (processedSize > 0) { + QSignalSpy spyResult(job, &KIO::Job::result); + const QString destToCheck = (!overwrite) ? destFile : destFile + QStringLiteral(".part"); QVERIFY2(QFile::exists(destToCheck), qPrintable(destToCheck)); if (suspend) { job->suspend(); } job->kill(); + + spyResult.wait(500); QVERIFY(!QFile::exists(destToCheck)); } }); + QVERIFY(!copyJob->exec()); QCOMPARE(spyProcessedSize.count(), 1); - // Give time to the kioslave to finish copy() and warn about chown/chmod failing (because FileCopyJob::doKill removed the file) - // Less confusing if the warnings show here. - QTest::qWait(500); - QVERIFY(!QFile::exists(destFile)); + + const QString destToCheck = (!overwrite) ? destFile : destFile + QStringLiteral(".part"); + QVERIFY(!QFile::exists(destToCheck)); } diff --git a/src/core/filecopyjob.cpp b/src/core/filecopyjob.cpp --- a/src/core/filecopyjob.cpp +++ b/src/core/filecopyjob.cpp @@ -578,21 +578,6 @@ bool FileCopyJob::doKill() { - Q_D(FileCopyJob); - - // If we are interrupted in the middle of file copying, - // we may end up with corrupted file at the destination. - // It is better to clean up this file. If a copy is being - // made as part of move operation then delete the dest only if - // source file is intact (m_delJob == NULL). - if (d->m_bFileCopyInProgress && d->m_copyJob && d->m_dest.isLocalFile()) { - if (d->m_flags & Overwrite) { - QFile::remove(d->m_dest.toLocalFile() + QStringLiteral(".part")); - } else { - QFile::remove(d->m_dest.toLocalFile()); - } - } - return Job::doKill(); } diff --git a/src/ioslaves/file/file_unix.cpp b/src/ioslaves/file/file_unix.cpp --- a/src/ioslaves/file/file_unix.cpp +++ b/src/ioslaves/file/file_unix.cpp @@ -261,7 +261,7 @@ bool use_sendfile = buff_src.st_size < 0x7FFFFFFF; #endif bool existing_dest_delete_attempted = false; - while (1) { + while (!wasKilled()) { #ifdef USE_SENDFILE if (use_sendfile) { off_t sf = processed_size; @@ -348,6 +348,15 @@ src_file.close(); dest_file.close(); + if (wasKilled()) { + qCDebug(KIO_FILE) << "Clean dest file after ioslave was killed:" << dest; + if (!QFile::remove(dest)) { // don't keep partly copied file + execWithElevatedPrivilege(DEL, {_dest}, errno); + } + finished(); + return; + } + if (dest_file.error() != QFile::NoError) { qCWarning(KIO_FILE) << "Error when closing file descriptor[2]:" << dest_file.errorString(); error(KIO::ERR_CANNOT_WRITE, dest); diff --git a/src/ioslaves/file/file_win.cpp b/src/ioslaves/file/file_win.cpp --- a/src/ioslaves/file/file_win.cpp +++ b/src/ioslaves/file/file_win.cpp @@ -182,6 +182,11 @@ return; } + if (wasKilled()) { + qCDebug(KIO_FILE) << "Clean dest file after ioslave was killed:" << dest; + QFile::remove(_dest); + } + finished(); }