diff --git a/.gitignore b/.gitignore index b52078ec9..c9031e681 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,14 @@ /.idea/ /.vscode/ /.cache/ +.omx/ +.opencode/ +.claude/ +.gemini/ +.cursor/ +.agent/ +.antigravity/ +.codex/ /tools/node_modules /tools/package-lock.json diff --git a/libs/linglong/src/linglong/package/uab_file.cpp b/libs/linglong/src/linglong/package/uab_file.cpp index f40b14880..7eef90146 100644 --- a/libs/linglong/src/linglong/package/uab_file.cpp +++ b/libs/linglong/src/linglong/package/uab_file.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -30,9 +30,10 @@ namespace linglong::package { -utils::error::Result> UABFile::loadFromFile(int fd) noexcept +utils::error::Result> +UABFile::loadFromFile(const std::string &path) noexcept { - LINGLONG_TRACE("load uab file from fd") + LINGLONG_TRACE("load uab file from path") struct EnableMaker : public UABFile { @@ -40,11 +41,17 @@ utils::error::Result> UABFile::loadFromFile(int fd) noe }; auto file = std::make_unique(); + file->setFileName(QString::fromStdString(path)); - if (!file->open(fd, QIODevice::ReadOnly, FileHandleFlag::AutoCloseHandle)) { + if (!file->open(QIODevice::ReadOnly)) { return LINGLONG_ERR(fmt::format("open uab failed: {}", file->errorString())); } + auto fd = file->handle(); + if (fd < 0) { + return LINGLONG_ERR(fmt::format("failed to get valid file descriptor from path: {}", path)); + } + elf_version(EV_CURRENT); auto *elf = elf_begin(fd, ELF_C_READ, nullptr); if (elf == nullptr) { @@ -332,19 +339,14 @@ utils::error::Result UABFile::extractSignData() noexcept seek(0); }); - auto selfFd = handle(); auto totalBytes = signSection->sh_size; std::array buf{}; while (totalBytes > 0) { auto bytesRead = totalBytes > buf.size() ? buf.size() : totalBytes; - auto readBytes = ::read(selfFd, buf.data(), bytesRead); + auto readBytes = this->read(reinterpret_cast(buf.data()), bytesRead); if (readBytes == -1) { - if (errno == EINTR) { - errno = 0; - continue; - } return LINGLONG_ERR( - fmt::format("read from sign section error: {}", common::error::errorString(errno))); + fmt::format("read from sign section error: {}", this->errorString().toStdString())); } while (true) { diff --git a/libs/linglong/src/linglong/package/uab_file.h b/libs/linglong/src/linglong/package/uab_file.h index db3d6ad5c..b2e32e448 100644 --- a/libs/linglong/src/linglong/package/uab_file.h +++ b/libs/linglong/src/linglong/package/uab_file.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -24,7 +24,8 @@ class UABFile : public QFile friend class MockUabFile; public: - static utils::error::Result> loadFromFile(int fd) noexcept; + static utils::error::Result> + loadFromFile(const std::string &path) noexcept; UABFile(UABFile &&) = delete; UABFile &operator=(UABFile &&) = delete; ~UABFile() override; diff --git a/libs/linglong/src/linglong/package_manager/package_manager.cpp b/libs/linglong/src/linglong/package_manager/package_manager.cpp index 3f20f68a5..3de244d1c 100644 --- a/libs/linglong/src/linglong/package_manager/package_manager.cpp +++ b/libs/linglong/src/linglong/package_manager/package_manager.cpp @@ -48,12 +48,16 @@ #include #include #include +#include #include +#include #include +#include #include #include +#include namespace linglong::service { @@ -84,6 +88,114 @@ QVariantMap toDBusReply(utils::error::ErrorCode code, } // namespace +CachedInstallFile::CachedInstallFile(std::string cachedFilePath) noexcept + : cachedFilePath(std::move(cachedFilePath)) +{ +} + +CachedInstallFile::~CachedInstallFile() +{ + if (this->cachedFilePath.empty()) { + return; + } + + std::error_code ec; + std::filesystem::remove(this->cachedFilePath, ec); + if (ec) { + LogW("failed to remove cached install file {}: {}", this->cachedFilePath, ec.message()); + } +} + +auto PackageManager::stageInstallFile(const QDBusUnixFileDescriptor &fd, + const QString &fileType, + const std::filesystem::path &cacheDir) noexcept + -> utils::error::Result> +{ + LINGLONG_TRACE("stage install file"); + + auto ensureRet = utils::ensureDirectory(cacheDir.string()); + if (!ensureRet) { + return LINGLONG_ERR("failed to prepare install cache directory", ensureRet); + } + + auto cachedPath = cacheDir + / fmt::format("install-from-file-{}.{}", + QUuid::createUuid().toString(QUuid::Id128).toStdString(), + fileType.toStdString()); + + auto inputFd = ::dup(fd.fileDescriptor()); + if (inputFd < 0) { + return LINGLONG_ERR(fmt::format("failed to duplicate install file descriptor: {}", + common::error::errorString(errno))); + } + auto closeInputFd = utils::finally::finally([&inputFd] { + if (inputFd >= 0) { + ::close(inputFd); + } + }); + + if (::lseek(inputFd, 0, SEEK_SET) == -1 && errno != ESPIPE) { + return LINGLONG_ERR(fmt::format("failed to rewind install file descriptor: {}", + common::error::errorString(errno))); + } + + auto outputFd = + ::open(cachedPath.c_str(), O_WRONLY | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC, 0600); + if (outputFd < 0) { + return LINGLONG_ERR(fmt::format("failed to create cached install file {}: {}", + cachedPath.string(), + common::error::errorString(errno))); + } + + bool keepCachedFile = false; + auto closeOutputFd = utils::finally::finally([&outputFd, &keepCachedFile, &cachedPath] { + if (outputFd >= 0) { + ::close(outputFd); + } + if (!keepCachedFile) { + std::error_code ec; + std::filesystem::remove(cachedPath, ec); + } + }); + + std::array buffer; + while (true) { + auto bytesRead = ::read(inputFd, buffer.data(), buffer.size()); + if (bytesRead == 0) { + break; + } + + if (bytesRead < 0) { + if (errno == EINTR) { + continue; + } + + return LINGLONG_ERR(fmt::format("failed to read install file descriptor: {}", + common::error::errorString(errno))); + } + + ssize_t bytesWrittenTotal = 0; + while (bytesWrittenTotal < bytesRead) { + auto bytesWritten = + ::write(outputFd, buffer.data() + bytesWrittenTotal, bytesRead - bytesWrittenTotal); + if (bytesWritten < 0) { + if (errno == EINTR) { + continue; + } + + return LINGLONG_ERR(fmt::format("failed to write cached install file {}: {}", + cachedPath.string(), + common::error::errorString(errno))); + } + + bytesWrittenTotal += bytesWritten; + } + } + + keepCachedFile = true; + return std::make_shared(cachedPath.string()); +} + PackageManager::PackageManager( std::unique_ptr repo, std::unique_ptr containerBuilder, @@ -477,10 +589,10 @@ void PackageManager::setConfiguration(const QVariantMap ¶meters) noexcept } } -QVariantMap PackageManager::installFromLayer(const QDBusUnixFileDescriptor &fd, +QVariantMap PackageManager::installFromLayer(const std::shared_ptr &stagedFile, const api::types::v1::CommonOptions &options) noexcept { - auto layerFileRet = package::LayerFile::New(fd.fileDescriptor()); + auto layerFileRet = package::LayerFile::New(QString::fromStdString(stagedFile->path())); if (!layerFileRet) { return toDBusReply(layerFileRet); } @@ -570,7 +682,7 @@ QVariantMap PackageManager::installFromLayer(const QDBusUnixFileDescriptor &fd, auto installer = [this, - fdDup = fd, // keep file descriptor don't close by the destructor of QDBusUnixFileDescriptor + fileDup = stagedFile, // keep file don't close by the destructor packageRef, layerFile = *layerFileRet, module = packageInfo.packageInfoV2Module, @@ -701,7 +813,7 @@ QVariantMap PackageManager::installFromLayer(const QDBusUnixFileDescriptor &fd, }); } -QVariantMap PackageManager::installFromUAB(const QDBusUnixFileDescriptor &fd, +QVariantMap PackageManager::installFromUAB(const std::shared_ptr &stagedFile, const api::types::v1::CommonOptions &options) noexcept { std::unique_ptr installHookManager = @@ -712,13 +824,13 @@ QVariantMap PackageManager::installFromUAB(const QDBusUnixFileDescriptor &fd, return toDBusReply(ret); } - ret = installHookManager->executeInstallHooks(fd.fileDescriptor()); + ret = installHookManager->executeInstallHooks(stagedFile->path()); if (!ret) { return toDBusReply(utils::error::ErrorCode::Failed, "uab package signature verification failed."); } - auto action = UabInstallationAction::create(fd.fileDescriptor(), *this, *repo, options); + auto action = UabInstallationAction::create(stagedFile, *this, *repo, options); if (!action) { return toDBusReply(utils::error::ErrorCode::Failed, "failed to create uab installation action"); @@ -740,19 +852,22 @@ auto PackageManager::InstallFromFile(const QDBusUnixFileDescriptor &fd, return toDBusReply(opts); } - const static QHash - installers = { { "layer", &PackageManager::installFromLayer }, - { "uab", &PackageManager::installFromUAB } }; - - if (!installers.contains(fileType)) { + if (fileType != "layer" && fileType != "uab") { auto msg = fmt::format("{} is unsupported fileType", fileType.toStdString()); return toDBusReply(utils::error::ErrorCode::AppInstallUnsupportedFileFormat, msg); } - return std::invoke(installers[fileType], this, fd, *opts); + auto stagedFile = + stageInstallFile(fd, fileType, std::filesystem::path(LINGLONG_ROOT) / "cache"); + if (!stagedFile) { + return toDBusReply(stagedFile); + } + + if (fileType == "layer") { + return installFromLayer(*stagedFile, *opts); + } + + return installFromUAB(*stagedFile, *opts); } auto PackageManager::Install(const QVariantMap ¶meters) noexcept -> QVariantMap diff --git a/libs/linglong/src/linglong/package_manager/package_manager.h b/libs/linglong/src/linglong/package_manager/package_manager.h index d86934392..4067b3fd4 100644 --- a/libs/linglong/src/linglong/package_manager/package_manager.h +++ b/libs/linglong/src/linglong/package_manager/package_manager.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -31,6 +32,22 @@ namespace linglong::service { class Action; +class CachedInstallFile +{ +public: + explicit CachedInstallFile(std::string cachedFilePath) noexcept; + ~CachedInstallFile(); + CachedInstallFile(const CachedInstallFile &) = delete; + CachedInstallFile(CachedInstallFile &&) = delete; + auto operator=(const CachedInstallFile &) -> CachedInstallFile & = delete; + auto operator=(CachedInstallFile &&) -> CachedInstallFile & = delete; + + [[nodiscard]] const std::string &path() const noexcept { return cachedFilePath; } + +private: + std::string cachedFilePath; +}; + class PackageManager : public QObject, protected QDBusContext { Q_OBJECT @@ -70,6 +87,11 @@ public // Nothing to do here, Permissions() will be rejected in org.deepin.linglong.PackageManager.conf void Permissions() { } + [[nodiscard]] static utils::error::Result> + stageInstallFile(const QDBusUnixFileDescriptor &fd, + const QString &fileType, + const std::filesystem::path &cacheDir) noexcept; + bool waitConfirm(PackageTask &taskRef, api::types::v1::InteractionMessageType msgType, const api::types::v1::PackageManager1RequestInteractionAdditionalMessage @@ -126,10 +148,10 @@ public void ReplyReceived(const QVariantMap &replies); private: - QVariantMap installFromLayer(const QDBusUnixFileDescriptor &fd, + QVariantMap installFromLayer(const std::shared_ptr &stagedFile, const api::types::v1::CommonOptions &options) noexcept; - QVariantMap installFromUAB(const QDBusUnixFileDescriptor &fd, + QVariantMap installFromUAB(const std::shared_ptr &stagedFile, const api::types::v1::CommonOptions &options) noexcept; [[nodiscard]] utils::error::Result lockRepo() noexcept; diff --git a/libs/linglong/src/linglong/package_manager/uab_installation.cpp b/libs/linglong/src/linglong/package_manager/uab_installation.cpp index f5b6ee579..f8acbbf79 100644 --- a/libs/linglong/src/linglong/package_manager/uab_installation.cpp +++ b/libs/linglong/src/linglong/package_manager/uab_installation.cpp @@ -1,18 +1,26 @@ -// SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2025 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later #include "uab_installation.h" +#include "linglong/common/error.h" +#include "linglong/utils/finally/finally.h" #include "linglong/utils/log/log.h" +#include +#include + namespace linglong::service { -std::shared_ptr UabInstallationAction::create( - int uabFD, PackageManager &pm, repo::OSTreeRepo &repo, api::types::v1::CommonOptions opts) +std::shared_ptr +UabInstallationAction::create(std::shared_ptr stagedFile, + PackageManager &pm, + repo::OSTreeRepo &repo, + api::types::v1::CommonOptions opts) { - auto p = new UabInstallationAction(uabFD, pm, repo, std::move(opts)); - return std::shared_ptr(p); + return std::shared_ptr( + new UabInstallationAction(std::move(stagedFile), pm, repo, std::move(opts))); } UabInstallationAction::CheckedLayers @@ -176,18 +184,13 @@ bool UabInstallationAction::extraModuleOnly(const std::vector stagedFile, PackageManager &pm, repo::OSTreeRepo &repo, api::types::v1::CommonOptions opts) : Action(pm, repo, opts) - , fd(dup(uabFD)) -{ -} - -UabInstallationAction::~UabInstallationAction() + , stagedFile(std::move(stagedFile)) { - close(fd); } utils::error::Result UabInstallationAction::prepare() @@ -198,9 +201,15 @@ utils::error::Result UabInstallationAction::prepare() return LINGLONG_OK; } - auto uabFileRet = package::UABFile::loadFromFile(fd); + if (!this->stagedFile) { + return LINGLONG_ERR("cached uab file missing"); + } + + auto uabFileRet = package::UABFile::loadFromFile(this->stagedFile->path()); if (!uabFileRet) { - return LINGLONG_ERR(fmt::format("failed to load uab file from fd {}", fd), uabFileRet); + return LINGLONG_ERR( + fmt::format("failed to load cached uab file from path {}", this->stagedFile->path()), + uabFileRet); } auto uabFile = std::move(uabFileRet).value(); diff --git a/libs/linglong/src/linglong/package_manager/uab_installation.h b/libs/linglong/src/linglong/package_manager/uab_installation.h index 2d83e041b..317738698 100644 --- a/libs/linglong/src/linglong/package_manager/uab_installation.h +++ b/libs/linglong/src/linglong/package_manager/uab_installation.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2025 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -14,6 +14,7 @@ #include "linglong/repo/ostree_repo.h" #include "linglong/utils/transaction.h" +#include #include #include @@ -22,10 +23,11 @@ namespace linglong::service { class UabInstallationAction : public Action { public: - static std::shared_ptr create(int uabFD, - PackageManager &pm, - repo::OSTreeRepo &repo, - api::types::v1::CommonOptions options); + static std::shared_ptr + create(std::shared_ptr stagedFile, + PackageManager &pm, + repo::OSTreeRepo &repo, + api::types::v1::CommonOptions options); using CheckedLayers = std::pair, std::vector>; @@ -37,7 +39,7 @@ class UabInstallationAction : public Action repo::OSTreeRepo &repo, const std::vector &layers); static bool extraModuleOnly(const std::vector &layers); - virtual ~UabInstallationAction(); + ~UabInstallationAction() override = default; virtual utils::error::Result prepare(); virtual utils::error::Result doAction(PackageTask &task); @@ -50,7 +52,7 @@ class UabInstallationAction : public Action virtual utils::error::Result postInstall(PackageTask &task); private: - UabInstallationAction(int uabFD, + UabInstallationAction(std::shared_ptr stagedFile, PackageManager &pm, repo::OSTreeRepo &repo, api::types::v1::CommonOptions options); @@ -60,7 +62,7 @@ class UabInstallationAction : public Action utils::error::Result installUabLayer(const std::vector &layers, std::optional subRef = std::nullopt); - int fd; + std::shared_ptr stagedFile; ActionOperation operation; std::string taskName; CheckedLayers checkedLayers; diff --git a/libs/linglong/tests/ll-tests/CMakeLists.txt b/libs/linglong/tests/ll-tests/CMakeLists.txt index fd0d621bb..f8a6f3d9a 100644 --- a/libs/linglong/tests/ll-tests/CMakeLists.txt +++ b/libs/linglong/tests/ll-tests/CMakeLists.txt @@ -31,6 +31,7 @@ pfl_add_executable( src/linglong/package/layer_dir_test.cpp src/linglong/package/layer_packager_test.cpp src/linglong/package_manager/action_test.cpp + src/linglong/package_manager/package_manager_test.cpp src/linglong/package_manager/task_test.cpp src/linglong/package_manager/task_queue_test.cpp src/linglong/package_manager/package_update_test.cpp diff --git a/libs/linglong/tests/ll-tests/src/linglong/package/uab_file_test.cpp b/libs/linglong/tests/ll-tests/src/linglong/package/uab_file_test.cpp index d2ca48b54..f5f4addd2 100644 --- a/libs/linglong/tests/ll-tests/src/linglong/package/uab_file_test.cpp +++ b/libs/linglong/tests/ll-tests/src/linglong/package/uab_file_test.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024-2026 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -120,12 +120,8 @@ std::unique_ptr UabFileTest::testDir; TEST_F(UabFileTest, UnpackFuseOffset) { - // 打开UAB文件 - int fd = open(uabFile.c_str(), O_RDONLY); - ASSERT_NE(fd, -1) << "Failed to open uab file" << strerror(errno); - // 初始化UABFile对象 - auto uab = linglong::package::UABFile::loadFromFile(fd); + auto uab = linglong::package::UABFile::loadFromFile(uabFile); ASSERT_TRUE(uab.has_value()) << "Failed to load uab file"; auto unpackRet = (*uab)->unpack(); ASSERT_TRUE(unpackRet.has_value()) diff --git a/libs/linglong/tests/ll-tests/src/linglong/package_manager/package_manager_test.cpp b/libs/linglong/tests/ll-tests/src/linglong/package_manager/package_manager_test.cpp new file mode 100644 index 000000000..5ccf5f910 --- /dev/null +++ b/libs/linglong/tests/ll-tests/src/linglong/package_manager/package_manager_test.cpp @@ -0,0 +1,125 @@ +/* + * SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#include + +#include "../../common/tempdir.h" +#include "linglong/package_manager/package_manager.h" +#include "linglong/package_manager/uab_installation.h" +#include "linglong/repo/ostree_repo.h" +#include "linglong/runtime/container_builder.h" +#include "ocppi/cli/crun/Crun.hpp" + +#include +#include +#include + +#include + +#include + +namespace { + +using namespace linglong; + +class TestRepo : public repo::OSTreeRepo +{ +public: + explicit TestRepo(const std::filesystem::path &path) + : repo::OSTreeRepo( + path, api::types::v1::RepoConfigV2{ .defaultRepo = "", .repos = {}, .version = 2 }) + { + } +}; + +class PackageManagerCacheTest : public ::testing::Test +{ +protected: + auto stageInstallFile(const QByteArray &payload, const QString &fileType) + -> std::shared_ptr + { + const auto sourcePath = sourceDir.path() / ("demo." + fileType.toStdString()); + QFile sourceFile(QString::fromStdString(sourcePath.string())); + EXPECT_TRUE(sourceFile.open(QIODevice::WriteOnly | QIODevice::Truncate)); + EXPECT_EQ(sourceFile.write(payload), payload.size()); + sourceFile.close(); + + const auto rawFd = ::open(sourcePath.c_str(), O_RDONLY | O_CLOEXEC); + EXPECT_GE(rawFd, 0); + + QDBusUnixFileDescriptor fd(rawFd); + auto stagedFile = service::PackageManager::stageInstallFile(fd, fileType, cacheDir.path()); + EXPECT_TRUE(stagedFile); + return *stagedFile; + } + + void SetUp() override + { + auto repoOwner = std::make_unique(cacheDir.path()); + repo = repoOwner.get(); + cli = ocppi::cli::crun::Crun::New(cacheDir.path()).value(); + auto containerBuilderOwner = std::make_unique(*cli); + pm = std::make_unique(std::move(repoOwner), + std::move(containerBuilderOwner), + nullptr); + } + + void TearDown() override + { + pm.reset(); + cli.reset(); + } + + TempDir sourceDir; + TempDir cacheDir; + repo::OSTreeRepo *repo{ nullptr }; + std::unique_ptr cli; + std::unique_ptr pm; +}; + +TEST_F(PackageManagerCacheTest, StageInstallFileCopiesPayloadIntoCacheDirectory) +{ + const QByteArray payload("install-from-file-cache-copy"); + auto stagedFile = stageInstallFile(payload, "uab"); + + EXPECT_TRUE(QFileInfo::exists(QString::fromStdString(stagedFile->path()))); + EXPECT_EQ(QFileInfo(QString::fromStdString(stagedFile->path())).absolutePath(), + QString::fromStdString(cacheDir.path().string())); + + QFile copiedFile(QString::fromStdString(stagedFile->path())); + ASSERT_TRUE(copiedFile.open(QIODevice::ReadOnly)); + EXPECT_EQ(copiedFile.readAll(), payload); +} + +TEST_F(PackageManagerCacheTest, CachedInstallFileRemovesStagedCopyOnDestruction) +{ + const QByteArray payload("install-from-file-cache-copy"); + auto stagedFile = stageInstallFile(payload, "uab"); + const auto stagedPath = stagedFile->path(); + + ASSERT_TRUE(QFileInfo::exists(QString::fromStdString(stagedPath))); + stagedFile.reset(); + + EXPECT_FALSE(QFileInfo::exists(QString::fromStdString(stagedPath))); +} + +TEST_F(PackageManagerCacheTest, UabInstallationActionKeepsStagedFileUntilActionDestruction) +{ + const QByteArray payload("install-from-file-cache-copy"); + auto stagedFile = stageInstallFile(payload, "uab"); + const auto stagedPath = stagedFile->path(); + + auto action = service::UabInstallationAction::create(stagedFile, *pm, *repo, {}); + + stagedFile.reset(); + ASSERT_TRUE(QFileInfo::exists(QString::fromStdString(stagedPath))); + + action.reset(); + + EXPECT_FALSE(QFileInfo::exists(QString::fromStdString(stagedPath))); +} + +} // namespace diff --git a/libs/utils/src/linglong/utils/hooks.cpp b/libs/utils/src/linglong/utils/hooks.cpp index e4eb8d06e..3392e0028 100644 --- a/libs/utils/src/linglong/utils/hooks.cpp +++ b/libs/utils/src/linglong/utils/hooks.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * SPDX-FileCopyrightText: 2025 - 2026 UnionTech Software Technology Co., Ltd. * * SPDX-License-Identifier: LGPL-3.0-or-later */ @@ -142,7 +142,8 @@ utils::error::Result InstallHookManager::parseInstallHooks() return LINGLONG_OK; } -utils::error::Result InstallHookManager::executeInstallHooks(int fd) noexcept +utils::error::Result +InstallHookManager::executeInstallHooks(const std::string &uabPath) noexcept { LINGLONG_TRACE("Executing pre-install hooks."); @@ -150,22 +151,6 @@ utils::error::Result InstallHookManager::executeInstallHooks(int fd) noexc return LINGLONG_OK; } - // Convert fd into a specific path using /proc/pid/fd/fd_num - std::ostringstream oss; - oss << "/proc/" << getpid() << "/fd/" << fd; - - std::array pathBuf{}; - auto size = readlink(oss.str().c_str(), pathBuf.data(), PATH_MAX); - - if (size == -1) { - return LINGLONG_ERR(fmt::format("Failed to read file link for fd {}: {}", - fd, - common::error::errorString(errno))); - } - - pathBuf[size] = '\0'; - std::string uabPath = pathBuf.data(); - std::vector> envVars = { { "LINGLONG_UAB_PATH", uabPath } }; return executeHookCommands(preInstallCommands, envVars); diff --git a/libs/utils/src/linglong/utils/hooks.h b/libs/utils/src/linglong/utils/hooks.h index 92a940b96..48fd00abd 100644 --- a/libs/utils/src/linglong/utils/hooks.h +++ b/libs/utils/src/linglong/utils/hooks.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * SPDX-FileCopyrightText: 2025 - 2026 UnionTech Software Technology Co., Ltd. * * SPDX-License-Identifier: LGPL-3.0-or-later */ @@ -24,7 +24,7 @@ class InstallHookManager final ~InstallHookManager() = default; utils::error::Result parseInstallHooks(); - utils::error::Result executeInstallHooks(int fd) noexcept; + utils::error::Result executeInstallHooks(const std::string &uabPath) noexcept; utils::error::Result executePostInstallHooks(const std::string &appID, const std::string &path) noexcept; utils::error::Result executePostUninstallHooks(const std::string &appID) noexcept;