diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/GpgContext.cpp | 167 | ||||
-rw-r--r-- | src/core/GpgContext.h | 3 | ||||
-rw-r--r-- | src/core/GpgInfo.h | 7 | ||||
-rw-r--r-- | src/core/function/gpg/GpgAdvancedOperator.cpp | 114 | ||||
-rw-r--r-- | src/core/function/gpg/GpgAdvancedOperator.h | 67 | ||||
-rw-r--r-- | src/core/function/gpg/GpgCommandExecutor.cpp | 128 | ||||
-rw-r--r-- | src/core/function/gpg/GpgCommandExecutor.h | 13 | ||||
-rw-r--r-- | src/core/function/gpg/GpgKeyOpera.cpp | 62 | ||||
-rw-r--r-- | src/core/thread/Task.cpp | 4 | ||||
-rw-r--r-- | src/core/thread/Task.h | 12 | ||||
-rw-r--r-- | src/core/thread/TaskRunner.cpp | 7 | ||||
-rw-r--r-- | src/core/thread/TaskRunner.h | 2 | ||||
-rw-r--r-- | src/core/thread/TaskRunnerGetter.h | 1 |
13 files changed, 481 insertions, 106 deletions
diff --git a/src/core/GpgContext.cpp b/src/core/GpgContext.cpp index 7ebd9fa9..59e21b84 100644 --- a/src/core/GpgContext.cpp +++ b/src/core/GpgContext.cpp @@ -31,11 +31,8 @@ #include <gpg-error.h> #include <gpgme.h> -#include <functional> -#include <string> -#include <utility> - #include "GpgConstants.h" +#include "core/function/gpg/GpgCommandExecutor.h" #ifdef _WIN32 #include <windows.h> @@ -240,6 +237,168 @@ gpgme_error_t GpgContext::test_status_cb(void *hook, const char *keyword, return GPG_ERR_NO_ERROR; } +const GpgInfo &GpgContext::GetInfo(bool refresh) { + if (!extend_info_loaded_ || refresh) { + GpgCommandExecutor::GetInstance().Execute( + info_.GpgConfPath, {"--list-components"}, + [=](int exit_code, const std::string &p_out, const std::string &p_err) { + LOG(INFO) << "gpgconf components exit_code" << exit_code + << "process stdout size" << p_out.size(); + + if (exit_code != 0) { + LOG(ERROR) << "gpgconf execute error, process stderr:" << p_err + << ", process stdout:" << p_out; + return; + } + + auto &components_info = info_.ComponentsInfo; + components_info["gpgme"] = {"GPG Made Easy", info_.GpgMEVersion, + _("Embedded In")}; + components_info["gpgconf"] = {"GPG Configure", "/", + info_.GpgConfPath}; + + std::vector<std::string> line_split_list; + boost::split(line_split_list, p_out, boost::is_any_of("\n")); + + for (const auto &line : line_split_list) { + std::vector<std::string> info_split_list; + boost::split(info_split_list, line, boost::is_any_of(":")); + LOG(INFO) << "gpgconf info line" << line << "info size" + << info_split_list.size(); + + if (info_split_list.size() != 3) continue; + + auto component_name = info_split_list[0]; + if (component_name == "gpg") { + components_info[component_name] = { + info_split_list[1], info_.GnupgVersion, info_split_list[2]}; + } else { + components_info[component_name] = {info_split_list[1], "/", + info_split_list[2]}; + } + } + }); + + GpgCommandExecutor::GetInstance().Execute( + info_.GpgConfPath, {"--list-dirs"}, + [=](int exit_code, const std::string &p_out, const std::string &p_err) { + LOG(INFO) << "gpgconf configurations exit_code" << exit_code + << "process stdout size" << p_out.size(); + + if (exit_code != 0) { + LOG(ERROR) << "gpgconf execute error, process stderr:" << p_err + << ", process stdout:" << p_out; + return; + } + + auto &configurations_info = info_.ConfigurationsInfo; + + std::vector<std::string> line_split_list; + boost::split(line_split_list, p_out, boost::is_any_of("\n")); + + for (const auto &line : line_split_list) { + std::vector<std::string> info_split_list; + boost::split(info_split_list, line, boost::is_any_of(":")); + LOG(INFO) << "gpgconf info line" << line << "info size" + << info_split_list.size(); + + if (info_split_list.size() != 2) continue; + + auto configuration_name = info_split_list[0]; + configurations_info[configuration_name] = {info_split_list[1]}; + } + }); + + for (const auto &component : info_.ComponentsInfo) { + LOG(INFO) << "gpgconf check options ready" + << "component" << component.first; + + if (component.first == "gpgme" || component.first == "gpgconf") continue; + + GpgCommandExecutor::GetInstance().Execute( + info_.GpgConfPath, {"--check-options", component.first}, + [=](int exit_code, const std::string &p_out, + const std::string &p_err) { + LOG(INFO) << "gpgconf options exit_code" << exit_code + << "process stdout size" << p_out.size() << "component" + << component.first; + + if (exit_code != 0) { + LOG(ERROR) << "gpgconf execute error, process stderr:" << p_err + << ", process stdout:" << p_out; + return; + } + + auto &options_info = info_.OptionsInfo; + + std::vector<std::string> line_split_list; + boost::split(line_split_list, p_out, boost::is_any_of("\n")); + + for (const auto &line : line_split_list) { + std::vector<std::string> info_split_list; + boost::split(info_split_list, line, boost::is_any_of(":")); + + LOG(INFO) << "gpgconf info line" << line << "info size" + << info_split_list.size(); + + if (info_split_list.size() != 6) continue; + + auto configuration_name = info_split_list[0]; + options_info[configuration_name] = { + info_split_list[1], info_split_list[2], info_split_list[3], + info_split_list[4], info_split_list[5]}; + } + }); + } + + for (const auto &component : info_.ComponentsInfo) { + LOG(INFO) << "gpgconf list options ready" + << "component" << component.first; + + if (component.first == "gpgme" || component.first == "gpgconf") continue; + + GpgCommandExecutor::GetInstance().Execute( + info_.GpgConfPath, {"--list-options", component.first}, + [=](int exit_code, const std::string &p_out, + const std::string &p_err) { + LOG(INFO) << "gpgconf options exit_code" << exit_code + << "process stdout size" << p_out.size() << "component" + << component.first; + + if (exit_code != 0) { + LOG(ERROR) << "gpgconf execute error, process stderr:" << p_err + << ", process stdout:" << p_out; + return; + } + + auto &available_options_info = info_.AvailableOptionsInfo; + + std::vector<std::string> line_split_list; + boost::split(line_split_list, p_out, boost::is_any_of("\n")); + + for (const auto &line : line_split_list) { + std::vector<std::string> info_split_list; + boost::split(info_split_list, line, boost::is_any_of(":")); + + LOG(INFO) << "gpgconf info line" << line << "info size" + << info_split_list.size(); + + if (info_split_list.size() != 10) continue; + + auto configuration_name = info_split_list[0]; + available_options_info[configuration_name] = { + info_split_list[1], info_split_list[2], info_split_list[3], + info_split_list[4], info_split_list[5], info_split_list[6], + info_split_list[7], info_split_list[8], info_split_list[9]}; + } + }); + } + + extend_info_loaded_ = true; + } + return info_; +} + void GpgContext::_ctx_ref_deleter::operator()(gpgme_ctx_t _ctx) { if (_ctx != nullptr) gpgme_release(_ctx); } diff --git a/src/core/GpgContext.h b/src/core/GpgContext.h index e1f1bda4..12a0fe1c 100644 --- a/src/core/GpgContext.h +++ b/src/core/GpgContext.h @@ -92,7 +92,7 @@ class GPGFRONTEND_CORE_EXPORT GpgContext * * @return const GpgInfo& */ - [[nodiscard]] const GpgInfo& GetInfo() const { return info_; } + [[nodiscard]] const GpgInfo& GetInfo(bool refresh = false); /** * @brief @@ -104,6 +104,7 @@ class GPGFRONTEND_CORE_EXPORT GpgContext private: GpgInfo info_; ///< GpgContextInitArgs args_; ///< + bool extend_info_loaded_ = false; /** * @brief diff --git a/src/core/GpgInfo.h b/src/core/GpgInfo.h index d0453b9f..53c5c3f5 100644 --- a/src/core/GpgInfo.h +++ b/src/core/GpgInfo.h @@ -42,9 +42,14 @@ class GpgInfo { std::string DatabasePath; ///< std::string GnupgVersion; ///< std::string GpgConfPath; ///< - std::string AssuanPath; ///< + std::string AssuanPath; ///< std::string CMSPath; ///< std::string GpgMEVersion; ///< + + std::map<std::string, std::vector<std::string>> ComponentsInfo; ///< + std::map<std::string, std::vector<std::string>> ConfigurationsInfo; ///< + std::map<std::string, std::vector<std::string>> OptionsInfo; ///< + std::map<std::string, std::vector<std::string>> AvailableOptionsInfo; ///< }; } // namespace GpgFrontend diff --git a/src/core/function/gpg/GpgAdvancedOperator.cpp b/src/core/function/gpg/GpgAdvancedOperator.cpp new file mode 100644 index 00000000..0ec447fe --- /dev/null +++ b/src/core/function/gpg/GpgAdvancedOperator.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2023. Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend 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 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +// +// Created by eric on 07.01.2023. +// + +#include "GpgAdvancedOperator.h" + +#include "core/function/gpg/GpgCommandExecutor.h" + +GpgFrontend::GpgAdvancedOperator::GpgAdvancedOperator(int channel) + : SingletonFunctionObject(channel) {} + +bool GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache() { + bool success = false; + GpgFrontend::GpgCommandExecutor::GetInstance().Execute( + ctx_.GetInfo().GpgConfPath, {"--reload", "gpg-agent"}, + [&](int exit_code, const std::string &p_out, const std::string &p_err) { + if (exit_code == 0) { + success = true; + } + }); + + return success; +} + +bool GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents() { + bool success = false; + GpgFrontend::GpgCommandExecutor::GetInstance().Execute( + ctx_.GetInfo().GpgConfPath, {"--reload"}, + [&](int exit_code, const std::string &p_out, const std::string &p_err) { + if (exit_code == 0) { + success = true; + } else { + LOG(ERROR) << "gpgconf execute error, process stderr:" << p_err + << ", process stdout:" << p_out; + return; + } + }); + + return success; +} + +bool GpgFrontend::GpgAdvancedOperator::RestartGpgComponents() { + bool success = false; + GpgFrontend::GpgCommandExecutor::GetInstance().Execute( + ctx_.GetInfo().GpgConfPath, {"--kill", "all"}, + [&](int exit_code, const std::string &p_out, const std::string &p_err) { + if (exit_code == 0) { + success = true; + } else { + LOG(ERROR) << "gpgconf execute error, process stderr:" << p_err + << ", process stdout:" << p_out; + return; + } + }); + + GpgFrontend::GpgCommandExecutor::GetInstance().Execute( + ctx_.GetInfo().GpgConfPath, {"--launch", "all"}, + [&](int exit_code, const std::string &p_out, const std::string &p_err) { + if (exit_code == 0) { + success = true; + } else { + success = false; + LOG(ERROR) << "gpgconf execute error, process stderr:" << p_err + << ", process stdout:" << p_out; + return; + } + }); + + return success; +} + +bool GpgFrontend::GpgAdvancedOperator::ResetConfigures() { + bool success = false; + GpgFrontend::GpgCommandExecutor::GetInstance().Execute( + ctx_.GetInfo().GpgConfPath, {"--apply-defaults"}, + [&](int exit_code, const std::string &p_out, const std::string &p_err) { + if (exit_code == 0) { + success = true; + } else { + LOG(ERROR) << "gpgconf execute error, process stderr:" << p_err + << ", process stdout:" << p_out; + return; + } + }); + + return success; +} diff --git a/src/core/function/gpg/GpgAdvancedOperator.h b/src/core/function/gpg/GpgAdvancedOperator.h new file mode 100644 index 00000000..267f1614 --- /dev/null +++ b/src/core/function/gpg/GpgAdvancedOperator.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023. Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend 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 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +// +// Created by eric on 07.01.2023. +// + +#ifndef GPGFRONTEND_GPGADVANCEDOPERATOR_H +#define GPGFRONTEND_GPGADVANCEDOPERATOR_H + +#include "core/GpgConstants.h" +#include "core/GpgContext.h" +#include "core/GpgFunctionObject.h" + +namespace GpgFrontend { + +class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator + : public SingletonFunctionObject<GpgAdvancedOperator> { + public: + /** + * @brief Construct a new Basic Operator object + * + * @param channel Channel corresponding to the context + */ + explicit GpgAdvancedOperator( + int channel = SingletonFunctionObject::GetDefaultChannel()); + + bool ClearGpgPasswordCache(); + + bool ReloadGpgComponents(); + + bool RestartGpgComponents(); + + bool ResetConfigures(); + + private: + GpgContext& ctx_ = GpgContext::GetInstance( + SingletonFunctionObject::GetChannel()); ///< Corresponding context +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGADVANCEDOPERATOR_H diff --git a/src/core/function/gpg/GpgCommandExecutor.cpp b/src/core/function/gpg/GpgCommandExecutor.cpp index 2292ed0e..0fe9b5c3 100644 --- a/src/core/function/gpg/GpgCommandExecutor.cpp +++ b/src/core/function/gpg/GpgCommandExecutor.cpp @@ -27,41 +27,119 @@ */ #include "GpgCommandExecutor.h" +#include "GpgFunctionObject.h" +#include "core/thread/TaskRunnerGetter.h" + GpgFrontend::GpgCommandExecutor::GpgCommandExecutor(int channel) : SingletonFunctionObject<GpgCommandExecutor>(channel) {} -#ifndef WINDOWS -#include <boost/asio.hpp> -#endif +void GpgFrontend::GpgCommandExecutor::Execute( + std::string cmd, std::vector<std::string> arguments, + std::function<void(int, std::string, std::string)> callback, + std::function<void(QProcess *)> interact_func) { + LOG(INFO) << "called" + << "cmd" << cmd << "arguments size" << arguments.size(); -#ifndef WINDOWS + Thread::Task::TaskCallback result_callback = + [](int rtn, Thread::Task::DataObjectPtr data_object) { + LOG(INFO) << "called"; -using boost::process::async_pipe; + if (data_object->GetObjectSize() != 4) + throw std::runtime_error("invalid data object size"); -void GpgFrontend::GpgCommandExecutor::Execute( - StringArgsRef arguments, - const std::function<void(async_pipe& in, async_pipe& out)>& interact_func) { - using namespace boost::process; + auto exit_code = data_object->PopObject<int>(); + auto process_stdout = data_object->PopObject<std::string>(); + auto process_stderr = data_object->PopObject<std::string>(); + auto callback = data_object->PopObject< + std::function<void(int, std::string, std::string)>>(); - boost::asio::io_service ios; + // call callback + callback(exit_code, process_stdout, process_stderr); + }; - std::vector<char> buf; + Thread::Task::TaskRunnable runner = + [](GpgFrontend::Thread::Task::DataObjectPtr data_object) -> int { + LOG(INFO) << "process runner called, data object size" + << data_object->GetObjectSize(); - async_pipe in_pipe_stream(ios); - async_pipe out_pipe_stream(ios); + if (data_object->GetObjectSize() != 4) + throw std::runtime_error("invalid data object size"); - child child_process(ctx_.GetInfo().AppPath.c_str(), arguments, - std_out > in_pipe_stream, std_in < out_pipe_stream); + // get arguments + auto cmd = data_object->PopObject<std::string>(); + LOG(INFO) << "get cmd" << cmd; + auto arguments = data_object->PopObject<std::vector<std::string>>(); + auto interact_func = + data_object->PopObject<std::function<void(QProcess *)>>(); - boost::asio::async_read( - in_pipe_stream, boost::asio::buffer(buf), - [&](const boost::system::error_code& ec, std::size_t size) { - interact_func(in_pipe_stream, out_pipe_stream); - }); + auto *cmd_process = new QProcess(); + cmd_process->setProcessChannelMode(QProcess::MergedChannels); - ios.run(); - child_process.wait(); - child_process.exit_code(); -} + QObject::connect(cmd_process, &QProcess::started, + []() -> void { LOG(INFO) << "process started"; }); + QObject::connect( + cmd_process, &QProcess::readyReadStandardOutput, + [interact_func, cmd_process]() { interact_func(cmd_process); }); + QObject::connect(cmd_process, &QProcess::errorOccurred, [=]() { + LOG(ERROR) << "error in executing command:" << cmd; + }); + QObject::connect(cmd_process, + qOverload<int, QProcess::ExitStatus>(&QProcess::finished), + [=](int, QProcess::ExitStatus status) { + if (status == QProcess::NormalExit) + LOG(INFO) << "succeed in executing command:" << cmd; + else + LOG(WARNING) << "error in executing command:" << cmd; + }); + + cmd_process->setProgram(QString::fromStdString(cmd)); + + QStringList q_arguments; + for (const auto &argument : arguments) + q_arguments.append(QString::fromStdString(argument)); + cmd_process->setArguments(q_arguments); + + LOG(INFO) << "process execute ready"; + + cmd_process->start(); + cmd_process->waitForFinished(30); + + std::string process_stdout = + cmd_process->readAllStandardOutput().toStdString(), + process_stderr = + cmd_process->readAllStandardError().toStdString(); + int exit_code = cmd_process->exitCode(); -#endif + cmd_process->close(); + cmd_process->deleteLater(); + + // transfer result + data_object->AppendObject(std::move(process_stderr)); + data_object->AppendObject(std::move(process_stdout)); + data_object->AppendObject(std::move(exit_code)); + + return 0; + }; + + // data transfer into task + auto data_object = std::make_shared<Thread::Task::DataObject>(); + data_object->AppendObject(std::move(callback)); + data_object->AppendObject(std::move(interact_func)); + data_object->AppendObject(std::move(arguments)); + data_object->AppendObject(std::move(cmd)); + + auto *process_task = new GpgFrontend::Thread::Task( + std::move(runner), std::move(result_callback), data_object); + + QEventLoop looper; + QObject::connect(process_task, &Thread::Task::SignalTaskFinished, &looper, + &QEventLoop::quit); + + GpgFrontend::Thread::TaskRunnerGetter::GetInstance() + .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_External_Process) + ->PostTask(process_task); + + // block until task finished + // this is to keep reference vaild until task finished + looper.exec(); +} diff --git a/src/core/function/gpg/GpgCommandExecutor.h b/src/core/function/gpg/GpgCommandExecutor.h index 40ee22df..c597feac 100644 --- a/src/core/function/gpg/GpgCommandExecutor.h +++ b/src/core/function/gpg/GpgCommandExecutor.h @@ -35,6 +35,7 @@ #include "core/GpgContext.h" #include "core/GpgFunctionObject.h" +#include "core/thread/Task.h" namespace GpgFrontend { @@ -53,19 +54,17 @@ class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor explicit GpgCommandExecutor( int channel = SingletonFunctionObject::GetDefaultChannel()); -#ifndef WINDOWS - /** * @brief Excuting an order * * @param arguments Command parameters * @param interact_func Command answering function */ - void Execute(StringArgsRef arguments, - const std::function<void(boost::process::async_pipe &in, - boost::process::async_pipe &out)> - &interact_func); -#endif + void Execute( + std::string cmd, std::vector<std::string> arguments, + std::function<void(int, std::string, std::string)> callback = + [](int, std::string, std::string) {}, + std::function<void(QProcess *)> interact_func = [](QProcess *) {}); private: GpgContext &ctx_ = GpgContext::GetInstance( diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp index 0839c132..08103bbb 100644 --- a/src/core/function/gpg/GpgKeyOpera.cpp +++ b/src/core/function/gpg/GpgKeyOpera.cpp @@ -103,59 +103,7 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire( * @return the process doing this job */ void GpgFrontend::GpgKeyOpera::GenerateRevokeCert( - const GpgKey& key, const std::string& output_file_name) { - auto args = std::vector<std::string>{"--no-tty", - "--command-fd", - "0", - "--status-fd", - "1", - "-o", - output_file_name, - "--gen-revoke", - key.GetFingerprint()}; - - using boost::asio::async_write; - using boost::process::async_pipe; -#ifndef WINDOWS - GpgCommandExecutor::GetInstance().Execute( - args, [](async_pipe& in, async_pipe& out) -> void { - // boost::asio::streambuf buff; - // boost::asio::read_until(in, buff, '\n'); - // - // std::istream is(&buff); - // - // while (!is.eof()) { - // std::string line; - // is >> line; - // LOG(INFO) << "line" << line; - // boost::algorithm::trim(line); - // if (line == std::string("[GNUPG:] GET_BOOL - // gen_revoke.okay")) { - // - // } else if (line == - // std::string( - // "[GNUPG:] GET_LINE - // ask_revocation_reason.code")) { - // - // } else if (line == - // std::string( - // "[GNUPG:] GET_LINE - // ask_revocation_reason.text")) { - // - // } else if (line == - // std::string("[GNUPG:] GET_BOOL - // openfile.overwrite.okay")) { - // - // } else if (line == - // std::string( - // "[GNUPG:] GET_BOOL - // ask_revocation_reason.okay")) { - // - // } - // } - }); -#endif -} + const GpgKey& key, const std::string& output_file_name) {} /** * Generate a new key pair @@ -181,9 +129,9 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey( GpgError err; - LOG(INFO) << "ctx version" << ctx_.GetInfo().GnupgVersion; + LOG(INFO) << "ctx version" << ctx_.GetInfo(false).GnupgVersion; - if (ctx_.GetInfo().GnupgVersion >= "2.1.0") { + if (ctx_.GetInfo(false).GnupgVersion >= "2.1.0") { unsigned int flags = 0; if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT; @@ -278,7 +226,7 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateSubkey( GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyPassword( const GpgFrontend::GpgKey& key) { - if (ctx_.GetInfo().GnupgVersion < "2.0.15") { + if (ctx_.GetInfo(false).GnupgVersion < "2.0.15") { LOG(ERROR) << _("operator not support"); return GPG_ERR_NOT_SUPPORTED; } @@ -287,7 +235,7 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyPassword( } GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyTOFUPolicy( const GpgFrontend::GpgKey& key, gpgme_tofu_policy_t tofu_policy) { - if (ctx_.GetInfo().GnupgVersion < "2.1.10") { + if (ctx_.GetInfo(false).GnupgVersion < "2.1.10") { LOG(ERROR) << _("operator not support"); return GPG_ERR_NOT_SUPPORTED; } diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index 6b1a27a1..669334d5 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -139,8 +139,8 @@ size_t GpgFrontend::Thread::Task::DataObject::GetObjectSize() { } void GpgFrontend::Thread::Task::DataObject::free_heap_ptr(Destructor *ptr) { - DLOG(TRACE) << "p_obj: " << ptr->p_obj << "destructor: " << ptr->destroy - << "DataObject:" << this; + LOG(TRACE) << "p_obj: " << ptr->p_obj << "destructor: " << ptr->destroy + << "DataObject:" << this; if (ptr->destroy != nullptr) { ptr->destroy(ptr->p_obj); } diff --git a/src/core/thread/Task.h b/src/core/thread/Task.h index c94baea6..163e1507 100644 --- a/src/core/thread/Task.h +++ b/src/core/thread/Task.h @@ -80,7 +80,8 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable { void AppendObject(T &&obj) { DLOG(TRACE) << "called:" << this; auto *obj_dstr = this->get_heap_ptr(sizeof(T)); - auto *ptr_heap = new ((void *)obj_dstr->p_obj) T(std::move(obj)); + new ((void *)obj_dstr->p_obj) T(std::forward<T>(obj)); + if (std::is_class_v<T>) { auto destructor = [](const void *x) { static_cast<const T *>(x)->~T(); @@ -89,7 +90,8 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable { } else { obj_dstr->destroy = nullptr; } - data_objects_.push(std::move(obj_dstr)); + + data_objects_.push(obj_dstr); } /** @@ -169,16 +171,16 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable { * * @param callback The callback function to be executed. */ - Task(TaskCallback callback, DataObjectPtr data_object = nullptr); + explicit Task(TaskCallback callback, DataObjectPtr data_object = nullptr); /** * @brief Construct a new Task object * * @param runnable */ - Task( + explicit Task( TaskRunnable runnable, - TaskCallback callback = [](int, std::shared_ptr<DataObject>) {}, + TaskCallback callback = [](int, const std::shared_ptr<DataObject> &) {}, DataObjectPtr data = nullptr); /** diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index f70b2d4c..ffbeb495 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -36,10 +36,11 @@ GpgFrontend::Thread::TaskRunner::TaskRunner() = default; GpgFrontend::Thread::TaskRunner::~TaskRunner() = default; void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) { + if (task == nullptr) return; + std::string uuid = task->GetUUID(); LOG(TRACE) << "Post Task" << uuid; - if (task == nullptr) return; task->setParent(nullptr); task->moveToThread(this); @@ -59,7 +60,7 @@ void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) { quit(); } -void GpgFrontend::Thread::TaskRunner::run() { +[[noreturn]] void GpgFrontend::Thread::TaskRunner::run() { LOG(TRACE) << "called" << "thread id:" << QThread::currentThreadId(); while (true) { @@ -91,7 +92,7 @@ void GpgFrontend::Thread::TaskRunner::run() { task->deleteLater(); pending_tasks_.erase(task->GetUUID()); } catch (...) { - LOG(ERROR) << "TaskRunner: Unknwon Exception in Task" + LOG(ERROR) << "TaskRunner: Unknown Exception in Task" << task->GetUUID(); // destroy the task, remove the task from the pending tasks diff --git a/src/core/thread/TaskRunner.h b/src/core/thread/TaskRunner.h index f18efca6..565c123c 100644 --- a/src/core/thread/TaskRunner.h +++ b/src/core/thread/TaskRunner.h @@ -55,7 +55,7 @@ class GPGFRONTEND_CORE_EXPORT TaskRunner : public QThread { * @brief * */ - void run() override; + [[noreturn]] void run() override; public slots: diff --git a/src/core/thread/TaskRunnerGetter.h b/src/core/thread/TaskRunnerGetter.h index afbf63af..80b25c3e 100644 --- a/src/core/thread/TaskRunnerGetter.h +++ b/src/core/thread/TaskRunnerGetter.h @@ -41,6 +41,7 @@ class GPGFRONTEND_CORE_EXPORT TaskRunnerGetter kTaskRunnerType_GPG, kTaskRunnerType_IO, kTaskRunnerType_Network, + kTaskRunnerType_External_Process, }; TaskRunnerGetter(int channel = SingletonFunctionObject::GetDefaultChannel()); |