Skip to content

Commit 9e3220f

Browse files
committed
refactor: use Cmd class for hook command execution
1. Replace std::system() calls with Cmd class for better process control 2. Remove escapeAndWrapCommandForShell function, now using Cmd.exec() with argument list 3. Replace EnvironmentVariableGuard with Cmd.setEnv() for environment handling 4. Simplify error handling by leveraging Cmd class result types 5. Update copyright year to 2025-2026 6. Remove unused includes (linglong/utils/env.h, cstdlib) Influence: 1. Test hook commands execution with valid commands 2. Verify hook commands with environment variables are properly set 3. Test error handling when hook commands fail 4. Verify pre-install, post-install, and post-uninstall hooks work correctly 5. Test commands with special characters and quotes 6. Verify proper error messages are returned for failed commands
1 parent 528dfab commit 9e3220f

1 file changed

Lines changed: 11 additions & 46 deletions

File tree

libs/utils/src/linglong/utils/hooks.cpp

Lines changed: 11 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
/*
2-
* SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd.
2+
* SPDX-FileCopyrightText: 2025 - 2026 UnionTech Software Technology Co., Ltd.
33
*
44
* SPDX-License-Identifier: LGPL-3.0-or-later
55
*/
66

77
#include "hooks.h"
88

9+
#include "cmd.h"
910
#include "configure.h"
1011
#include "linglong/common/error.h"
11-
#include "linglong/utils/env.h"
1212
#include "linglong/utils/error/error.h"
1313
#include "linglong/utils/log/log.h"
1414

1515
#include <fmt/format.h>
1616

1717
#include <array>
1818
#include <climits>
19-
#include <cstdlib>
2019
#include <cstring>
2120
#include <filesystem>
2221
#include <fstream>
@@ -33,58 +32,24 @@ constexpr std::string_view PRE_INSTALL_ACTION_PREFIX = "ll-pre-install=";
3332
constexpr std::string_view POST_INSTALL_ACTION_PREFIX = "ll-post-install=";
3433
constexpr std::string_view POST_UNINSTALL_ACTION_PREFIX = "ll-post-uninstall=";
3534

36-
// This function ensures the command string is safely wrapped for 'sh -c'.
37-
static std::string escapeAndWrapCommandForShell(const std::string &command)
38-
{
39-
std::string escapedCommand = command;
40-
size_t pos = 0;
41-
// Replace ' with '\'' (close current quote, add literal single quote, open new quote)
42-
while ((pos = escapedCommand.find('\'', pos)) != std::string::npos) {
43-
escapedCommand.replace(pos, 1, "'\\''");
44-
pos += 4;
45-
}
46-
47-
return "sh -c " + escapedCommand;
48-
}
49-
5035
using CommandList = const std::vector<std::string> &;
5136

5237
utils::error::Result<void> executeHookCommands(
5338
CommandList commands, const std::vector<std::pair<std::string, std::string>> &envVars) noexcept
5439
{
55-
LINGLONG_TRACE("Executing command");
40+
LINGLONG_TRACE("Executing hook commands");
5641

57-
std::vector<std::unique_ptr<EnvironmentVariableGuard>> envVarGuards;
58-
envVarGuards.reserve(envVars.size());
59-
for (const auto &pair : envVars) {
60-
envVarGuards.emplace_back(
61-
std::make_unique<EnvironmentVariableGuard>(pair.first, pair.second));
62-
}
42+
for (const auto &command : commands) {
43+
Cmd cmd("sh");
6344

64-
for (const auto &command_raw : commands) {
65-
std::string fullCommand = escapeAndWrapCommandForShell(command_raw);
66-
67-
int ret = std::system(fullCommand.c_str());
68-
69-
if (ret == -1) {
70-
return LINGLONG_ERR(fmt::format("Failed to execute command: '{}'. System error: {}.",
71-
fullCommand,
72-
common::error::errorString(errno)));
45+
for (const auto &[name, value] : envVars) {
46+
cmd.setEnv(name, value);
7347
}
7448

75-
if (!WIFEXITED(ret)) {
76-
int signalNum = WTERMSIG(ret);
77-
return LINGLONG_ERR(fmt::format("Command '{}' terminated by signal {} ({}).",
78-
fullCommand,
79-
signalNum,
80-
strsignal(signalNum)));
81-
}
82-
83-
int exitStatus = WEXITSTATUS(ret);
84-
if (exitStatus != 0) {
85-
return LINGLONG_ERR(fmt::format("Command '{}' exited with non-zero status: {}.",
86-
fullCommand,
87-
exitStatus));
49+
auto result = cmd.exec({ "-c", command });
50+
if (!result.has_value()) {
51+
return LINGLONG_ERR(
52+
fmt::format("Hook command '{}' failed: {}.", command, result.error()));
8853
}
8954
}
9055
return LINGLONG_OK;

0 commit comments

Comments
 (0)