Changeset View
Changeset View
Standalone View
Standalone View
src/core/filecopyjob.cpp
Show All 14 Lines | 1 | /* This file is part of the KDE libraries | |||
---|---|---|---|---|---|
15 | You should have received a copy of the GNU Library General Public License | 15 | You should have received a copy of the GNU Library General Public License | ||
16 | along with this library; see the file COPYING.LIB. If not, write to | 16 | along with this library; see the file COPYING.LIB. If not, write to | ||
17 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 17 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | 18 | Boston, MA 02110-1301, USA. | ||
19 | */ | 19 | */ | ||
20 | 20 | | |||
21 | #include "filecopyjob.h" | 21 | #include "filecopyjob.h" | ||
22 | #include "job_p.h" | 22 | #include "job_p.h" | ||
23 | #include <QFile> | ||||
23 | #include <QTimer> | 24 | #include <QTimer> | ||
24 | #include "kprotocolmanager.h" | 25 | #include "kprotocolmanager.h" | ||
25 | #include "scheduler.h" | 26 | #include "scheduler.h" | ||
26 | #include "slave.h" | 27 | #include "slave.h" | ||
27 | #include <KLocalizedString> | 28 | #include <KLocalizedString> | ||
28 | 29 | | |||
29 | using namespace KIO; | 30 | using namespace KIO; | ||
30 | 31 | | |||
31 | static inline Slave *jobSlave(SimpleJob *job) | 32 | static inline Slave *jobSlave(SimpleJob *job) | ||
32 | { | 33 | { | ||
33 | return SimpleJobPrivate::get(job)->m_slave; | 34 | return SimpleJobPrivate::get(job)->m_slave; | ||
34 | } | 35 | } | ||
35 | 36 | | |||
36 | /** @internal */ | 37 | /** @internal */ | ||
37 | class KIO::FileCopyJobPrivate: public KIO::JobPrivate | 38 | class KIO::FileCopyJobPrivate: public KIO::JobPrivate | ||
38 | { | 39 | { | ||
39 | public: | 40 | public: | ||
40 | FileCopyJobPrivate(const QUrl &src, const QUrl &dest, int permissions, | 41 | FileCopyJobPrivate(const QUrl &src, const QUrl &dest, int permissions, | ||
41 | bool move, JobFlags flags) | 42 | bool move, JobFlags flags) | ||
42 | : m_sourceSize(filesize_t(-1)), m_src(src), m_dest(dest), m_moveJob(nullptr), m_copyJob(nullptr), m_delJob(nullptr), | 43 | : m_sourceSize(filesize_t(-1)), m_src(src), m_dest(dest), m_moveJob(nullptr), m_copyJob(nullptr), m_delJob(nullptr), | ||
43 | m_chmodJob(nullptr), m_getJob(nullptr), m_putJob(nullptr), m_permissions(permissions), | 44 | m_chmodJob(nullptr), m_getJob(nullptr), m_putJob(nullptr), m_permissions(permissions), | ||
44 | m_move(move), m_mustChmod(0), m_flags(flags) | 45 | m_move(move), m_mustChmod(0), m_bFileCopyInProgress(false), m_flags(flags) | ||
45 | { | 46 | { | ||
46 | } | 47 | } | ||
47 | KIO::filesize_t m_sourceSize; | 48 | KIO::filesize_t m_sourceSize; | ||
48 | QDateTime m_modificationTime; | 49 | QDateTime m_modificationTime; | ||
49 | QUrl m_src; | 50 | QUrl m_src; | ||
50 | QUrl m_dest; | 51 | QUrl m_dest; | ||
51 | QByteArray m_buffer; | 52 | QByteArray m_buffer; | ||
52 | SimpleJob *m_moveJob; | 53 | SimpleJob *m_moveJob; | ||
53 | SimpleJob *m_copyJob; | 54 | SimpleJob *m_copyJob; | ||
54 | SimpleJob *m_delJob; | 55 | SimpleJob *m_delJob; | ||
55 | SimpleJob *m_chmodJob; | 56 | SimpleJob *m_chmodJob; | ||
56 | TransferJob *m_getJob; | 57 | TransferJob *m_getJob; | ||
57 | TransferJob *m_putJob; | 58 | TransferJob *m_putJob; | ||
58 | int m_permissions; | 59 | int m_permissions; | ||
59 | bool m_move: 1; | 60 | bool m_move: 1; | ||
60 | bool m_canResume: 1; | 61 | bool m_canResume: 1; | ||
61 | bool m_resumeAnswerSent: 1; | 62 | bool m_resumeAnswerSent: 1; | ||
62 | bool m_mustChmod: 1; | 63 | bool m_mustChmod: 1; | ||
64 | bool m_bFileCopyInProgress: 1; | ||||
63 | JobFlags m_flags; | 65 | JobFlags m_flags; | ||
64 | 66 | | |||
65 | void startBestCopyMethod(); | 67 | void startBestCopyMethod(); | ||
66 | void startCopyJob(); | 68 | void startCopyJob(); | ||
67 | void startCopyJob(const QUrl &slave_url); | 69 | void startCopyJob(const QUrl &slave_url); | ||
68 | void startRenameJob(const QUrl &slave_url); | 70 | void startRenameJob(const QUrl &slave_url); | ||
69 | void startDataPump(); | 71 | void startDataPump(); | ||
70 | void connectSubjob(SimpleJob *job); | 72 | void connectSubjob(SimpleJob *job); | ||
▲ Show 20 Lines • Show All 165 Lines • ▼ Show 20 Line(s) | 237 | { | |||
236 | Q_Q(FileCopyJob); | 238 | Q_Q(FileCopyJob); | ||
237 | q->connect(job, &KJob::totalSize, q, [q](KJob *job, qulonglong totalSize) { | 239 | q->connect(job, &KJob::totalSize, q, [q](KJob *job, qulonglong totalSize) { | ||
238 | Q_UNUSED(job); | 240 | Q_UNUSED(job); | ||
239 | if (totalSize != q->totalAmount(KJob::Bytes)) { | 241 | if (totalSize != q->totalAmount(KJob::Bytes)) { | ||
240 | q->setTotalAmount(KJob::Bytes, totalSize); | 242 | q->setTotalAmount(KJob::Bytes, totalSize); | ||
241 | } | 243 | } | ||
242 | }); | 244 | }); | ||
243 | 245 | | |||
244 | q->connect(job, &KJob::processedSize, q, [q](KJob *job, qulonglong processedSize) { | 246 | q->connect(job, &KJob::processedSize, q, [q, this](KJob *job, qulonglong processedSize) { | ||
245 | Q_UNUSED(job); | 247 | if (job == m_copyJob) { | ||
248 | m_bFileCopyInProgress = processedSize > 0; | ||||
249 | } | ||||
246 | q->setProcessedAmount(KJob::Bytes, processedSize); | 250 | q->setProcessedAmount(KJob::Bytes, processedSize); | ||
247 | }); | 251 | }); | ||
248 | 252 | | |||
249 | q->connect(job, QOverload<KJob*,ulong>::of(&KJob::percent), q, [q](KJob *job, ulong percent) { | 253 | q->connect(job, QOverload<KJob*,ulong>::of(&KJob::percent), q, [q](KJob *job, ulong percent) { | ||
250 | Q_UNUSED(job); | 254 | Q_UNUSED(job); | ||
251 | if (percent > q->percent()) { | 255 | if (percent > q->percent()) { | ||
252 | q->setPercent(percent); | 256 | q->setPercent(percent); | ||
253 | } | 257 | } | ||
▲ Show 20 Lines • Show All 210 Lines • ▼ Show 20 Line(s) | 466 | { | |||
464 | emit q->mimetype(q, type); | 468 | emit q->mimetype(q, type); | ||
465 | } | 469 | } | ||
466 | 470 | | |||
467 | void FileCopyJob::slotResult(KJob *job) | 471 | void FileCopyJob::slotResult(KJob *job) | ||
468 | { | 472 | { | ||
469 | Q_D(FileCopyJob); | 473 | Q_D(FileCopyJob); | ||
470 | //qDebug() << "this=" << this << "job=" << job; | 474 | //qDebug() << "this=" << this << "job=" << job; | ||
471 | removeSubjob(job); | 475 | removeSubjob(job); | ||
476 | | ||||
477 | // If result comes from copyjob then we are not writing anymore. | ||||
478 | if (job == d->m_copyJob) { | ||||
dfaure: Why the "probably"? ;-) | |||||
479 | d->m_bFileCopyInProgress = false; | ||||
"file write" sounds like putJob, which isn't what this is about. I guess this should be called d->m_bFileCopyInProgress instead. dfaure: "file write" sounds like putJob, which isn't what this is about.
I guess this should be called… | |||||
480 | } | ||||
481 | | ||||
472 | // Did job have an error ? | 482 | // Did job have an error ? | ||
473 | if (job->error()) { | 483 | if (job->error()) { | ||
474 | if ((job == d->m_moveJob) && (job->error() == ERR_UNSUPPORTED_ACTION)) { | 484 | if ((job == d->m_moveJob) && (job->error() == ERR_UNSUPPORTED_ACTION)) { | ||
475 | d->m_moveJob = nullptr; | 485 | d->m_moveJob = nullptr; | ||
476 | d->startBestCopyMethod(); | 486 | d->startBestCopyMethod(); | ||
477 | return; | 487 | return; | ||
478 | } else if ((job == d->m_copyJob) && (job->error() == ERR_UNSUPPORTED_ACTION)) { | 488 | } else if ((job == d->m_copyJob) && (job->error() == ERR_UNSUPPORTED_ACTION)) { | ||
479 | d->m_copyJob = nullptr; | 489 | d->m_copyJob = nullptr; | ||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Line(s) | 570 | if (job == d->m_chmodJob) { | |||
561 | d->m_chmodJob = nullptr; // Finished | 571 | d->m_chmodJob = nullptr; // Finished | ||
562 | } | 572 | } | ||
563 | 573 | | |||
564 | if (!hasSubjobs()) { | 574 | if (!hasSubjobs()) { | ||
565 | emitResult(); | 575 | emitResult(); | ||
566 | } | 576 | } | ||
567 | } | 577 | } | ||
568 | 578 | | |||
579 | bool FileCopyJob::doKill() | ||||
580 | { | ||||
581 | Q_D(FileCopyJob); | ||||
582 | | ||||
583 | // If we are interrupted in the middle of file copying, | ||||
584 | // we may end up with corrupted file at the destination. | ||||
585 | // It is better to clean up this file. If a copy is being | ||||
586 | // made as part of move operation then delete the dest only if | ||||
587 | // source file is intact (m_delJob == NULL). | ||||
588 | if (d->m_bFileCopyInProgress && d->m_copyJob && d->m_dest.isLocalFile()) { | ||||
dfaure: Why "not suspended"? If we suspend and kill, don't we want the cleanup? | |||||
589 | if (d->m_flags & Overwrite) { | ||||
This if makes little sense as is, since d->m_delJob can only be set when d->m_copyJob is nullptr (see line 515). So it's redundant, and the same as writing if (d->m_copyJob) -- and it looks less scary, I was initially worried when reading your line about what would happen before m_delJob was set or after m_delJob was null again. dfaure: This `if` makes little sense as is, since `d->m_delJob` can only be set when `d->m_copyJob` is… | |||||
590 | QFile::remove(d->m_dest.toLocalFile() + QStringLiteral(".part")); | ||||
dfaure: A test for isLocalFile() is missing first. | |||||
591 | } else { | ||||
592 | QFile::remove(d->m_dest.toLocalFile()); | ||||
593 | } | ||||
594 | } | ||||
595 | | ||||
596 | return Job::doKill(); | ||||
597 | } | ||||
598 | | ||||
569 | FileCopyJob *KIO::file_copy(const QUrl &src, const QUrl &dest, int permissions, | 599 | FileCopyJob *KIO::file_copy(const QUrl &src, const QUrl &dest, int permissions, | ||
570 | JobFlags flags) | 600 | JobFlags flags) | ||
571 | { | 601 | { | ||
572 | return FileCopyJobPrivate::newJob(src, dest, permissions, false, flags); | 602 | return FileCopyJobPrivate::newJob(src, dest, permissions, false, flags); | ||
573 | } | 603 | } | ||
574 | 604 | | |||
575 | FileCopyJob *KIO::file_move(const QUrl &src, const QUrl &dest, int permissions, | 605 | FileCopyJob *KIO::file_move(const QUrl &src, const QUrl &dest, int permissions, | ||
576 | JobFlags flags) | 606 | JobFlags flags) | ||
Show All 9 Lines |
Why the "probably"? ;-)