qt: Remove left-over partial files more persistently
* lang/qt/src/Makefile.am: Add new files. * lang/qt/src/cleaner.cpp, lang/qt/src/cleaner.h: New. * lang/qt/src/util.cpp (PartialFileGuard::~PartialFileGuard): Call Cleaner::removeFile instead of removeFile. * lang/qt/src/util.cpp, lang/qt/src/util.h (removeFile): Remove. -- If the initial attempt to remove the file fails then a Cleaner is created that tries to remove the file at regular intervals (10 s) and on destruction (which happens on application shutdown). GnuPG-bug-id: 6584
This commit is contained in:
parent
185ab7d7ba
commit
278f92b189
@ -32,6 +32,7 @@ EXTRA_DIST = QGpgmeConfig.cmake.in.in QGpgmeConfigVersion.cmake.in \
|
||||
QGpgmeQt6Config-w32.cmake.in.in QGpgmeQt6ConfigVersion.cmake.in
|
||||
|
||||
qgpgme_sources = \
|
||||
cleaner.cpp \
|
||||
dataprovider.cpp \
|
||||
debug.cpp \
|
||||
decryptverifyarchivejob.cpp \
|
||||
@ -176,6 +177,7 @@ camelcase_headers= \
|
||||
|
||||
private_qgpgme_headers = \
|
||||
changeexpiryjob_p.h \
|
||||
cleaner.h \
|
||||
decryptverifyarchivejob_p.h \
|
||||
encryptarchivejob_p.h \
|
||||
encryptjob_p.h \
|
||||
@ -235,6 +237,7 @@ qgpgme_moc_sources = \
|
||||
changeexpiryjob.moc \
|
||||
changeownertrustjob.moc \
|
||||
changepasswdjob.moc \
|
||||
cleaner.moc \
|
||||
decryptjob.moc \
|
||||
decryptverifyarchivejob.moc \
|
||||
decryptverifyjob.moc \
|
||||
|
99
lang/qt/src/cleaner.cpp
Normal file
99
lang/qt/src/cleaner.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
cleaner.cpp
|
||||
|
||||
This file is part of qgpgme, the Qt API binding for gpgme
|
||||
Copyright (c) 2023 g10 Code GmbH
|
||||
Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
|
||||
|
||||
QGpgME is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
QGpgME is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of this program with any edition of
|
||||
the Qt library by Trolltech AS, Norway (or with modified versions
|
||||
of Qt that use the same license as Qt), and distribute linked
|
||||
combinations including the two. You must obey the GNU General
|
||||
Public License in all respects for all of the code used other than
|
||||
Qt. If you modify this file, you may extend this exception to
|
||||
your version of the file, but you are not obligated to do so. If
|
||||
you do not wish to do so, delete this exception statement from
|
||||
your version.
|
||||
*/
|
||||
|
||||
#include "cleaner.h"
|
||||
|
||||
#include <qgpgme_debug.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QFile>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
static const auto timeout = std::chrono::seconds{10};
|
||||
|
||||
static bool remove_file(const QString &filePath)
|
||||
{
|
||||
if (filePath.isEmpty()) {
|
||||
qCWarning(QGPGME_LOG) << __func__ << "- called with empty file path";
|
||||
return true;
|
||||
}
|
||||
if (QFile::exists(filePath)) {
|
||||
qCDebug(QGPGME_LOG) << __func__ << "- Removing file" << filePath;
|
||||
if (!QFile::remove(filePath)) {
|
||||
qCDebug(QGPGME_LOG) << __func__ << "- Removing file" << filePath << "failed";
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
qCDebug(QGPGME_LOG) << __func__ << "- File" << filePath << "doesn't exist";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Cleaner::removeFile(const QString &filePath)
|
||||
{
|
||||
if (!remove_file(filePath)) {
|
||||
// use invokeMethod because we might not be called from the GUI thread
|
||||
// but we want to delegate the Cleaner's clean-up to the application instance
|
||||
QMetaObject::invokeMethod(qApp, [filePath]() {
|
||||
new Cleaner{filePath, qApp};
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
|
||||
Cleaner::Cleaner(const QString &filePath, QObject *parent)
|
||||
: QObject{parent}
|
||||
, mFilePath{filePath}
|
||||
{
|
||||
qCDebug(QGPGME_LOG) << this << __func__ << filePath;
|
||||
mTimer.setSingleShot(true);
|
||||
mTimer.callOnTimeout([this]() {
|
||||
if (remove_file(mFilePath)) {
|
||||
mFilePath.clear();
|
||||
deleteLater();
|
||||
} else {
|
||||
mTimer.start(timeout);
|
||||
}
|
||||
});
|
||||
mTimer.start(timeout);
|
||||
}
|
||||
|
||||
Cleaner::~Cleaner()
|
||||
{
|
||||
qCDebug(QGPGME_LOG) << this << __func__;
|
||||
if (!mFilePath.isEmpty()) {
|
||||
remove_file(mFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
#include "cleaner.moc"
|
60
lang/qt/src/cleaner.h
Normal file
60
lang/qt/src/cleaner.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
cleaner.h
|
||||
|
||||
This file is part of qgpgme, the Qt API binding for gpgme
|
||||
Copyright (c) 2023 g10 Code GmbH
|
||||
Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
|
||||
|
||||
QGpgME is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
QGpgME is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of this program with any edition of
|
||||
the Qt library by Trolltech AS, Norway (or with modified versions
|
||||
of Qt that use the same license as Qt), and distribute linked
|
||||
combinations including the two. You must obey the GNU General
|
||||
Public License in all respects for all of the code used other than
|
||||
Qt. If you modify this file, you may extend this exception to
|
||||
your version of the file, but you are not obligated to do so. If
|
||||
you do not wish to do so, delete this exception statement from
|
||||
your version.
|
||||
*/
|
||||
|
||||
#ifndef __QGPGME_CLEANER_H__
|
||||
#define __QGPGME_CLEANER_H__
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
|
||||
/** Helper class that tries to remove files at regular intervals and on destruction. */
|
||||
class Cleaner : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/** Tries to remove the file. If this fails it creates a Cleaner for the file. */
|
||||
static void removeFile(const QString &filePath);
|
||||
|
||||
private:
|
||||
explicit Cleaner(const QString &filePath, QObject *parent=nullptr);
|
||||
~Cleaner() override;
|
||||
|
||||
Q_DISABLE_COPY_MOVE(Cleaner)
|
||||
|
||||
private:
|
||||
QString mFilePath;
|
||||
QTimer mTimer;
|
||||
};
|
||||
|
||||
#endif // __QGPGME_CLEANER_H__
|
@ -37,6 +37,7 @@
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#include "cleaner.h"
|
||||
#include "qgpgme_debug.h"
|
||||
|
||||
#include <QFile>
|
||||
@ -68,17 +69,6 @@ QStringList toFingerprints(const std::vector<GpgME::Key> &keys)
|
||||
return fprs;
|
||||
}
|
||||
|
||||
void removeFile(const QString &fileName)
|
||||
{
|
||||
if (QFile::exists(fileName)) {
|
||||
if (QFile::remove(fileName)) {
|
||||
qCDebug(QGPGME_LOG) << __func__ << "- Removed file" << fileName;
|
||||
} else {
|
||||
qCDebug(QGPGME_LOG) << __func__ << "- Removing file" << fileName << "failed";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a string of random characters for the file names of temporary files.
|
||||
* Never use this for generating passwords or similar use cases requiring highly
|
||||
@ -157,7 +147,7 @@ PartialFileGuard::PartialFileGuard(const QString &fileName)
|
||||
PartialFileGuard::~PartialFileGuard()
|
||||
{
|
||||
if (!mTempFileName.isEmpty()) {
|
||||
removeFile(mTempFileName);
|
||||
Cleaner::removeFile(mTempFileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,8 +55,6 @@ std::vector<std::string> toStrings(const QStringList &l);
|
||||
|
||||
QStringList toFingerprints(const std::vector<GpgME::Key> &keys);
|
||||
|
||||
void removeFile(const QString &fileName);
|
||||
|
||||
/**
|
||||
* Helper for using a temporary "part" file for writing a result to, similar
|
||||
* to what browsers do when downloading files.
|
||||
|
Loading…
Reference in New Issue
Block a user