Kevin Tung | a2eb951 | 2025-05-05 18:28:56 +0800 | [diff] [blame] | 1 | #include "common/include/utils.hpp" |
| 2 | |
| 3 | #include <phosphor-logging/lg2.hpp> |
| 4 | |
| 5 | PHOSPHOR_LOG2_USING; |
| 6 | |
Kevin Tung | c538727 | 2025-07-28 18:10:43 +0800 | [diff] [blame] | 7 | sdbusplus::async::task<bool> asyncSystem( |
| 8 | sdbusplus::async::context& ctx, const std::string& cmd, |
| 9 | std::optional<std::reference_wrapper<std::string>> result) |
Kevin Tung | a2eb951 | 2025-05-05 18:28:56 +0800 | [diff] [blame] | 10 | { |
Kevin Tung | c538727 | 2025-07-28 18:10:43 +0800 | [diff] [blame] | 11 | int exitPipefd[2]; |
| 12 | int resultPipefd[2]; |
| 13 | |
| 14 | if (pipe(exitPipefd) == -1 || (result && pipe(resultPipefd) == -1)) |
Kevin Tung | a2eb951 | 2025-05-05 18:28:56 +0800 | [diff] [blame] | 15 | { |
| 16 | error("Failed to create pipe for command: {CMD}", "CMD", cmd); |
| 17 | co_return false; |
| 18 | } |
| 19 | |
| 20 | pid_t pid = fork(); |
| 21 | if (pid == 0) |
| 22 | { |
Kevin Tung | c538727 | 2025-07-28 18:10:43 +0800 | [diff] [blame] | 23 | close(exitPipefd[0]); |
| 24 | |
| 25 | if (result) |
| 26 | { |
| 27 | close(resultPipefd[0]); |
| 28 | dup2(resultPipefd[1], STDOUT_FILENO); |
| 29 | dup2(resultPipefd[1], STDERR_FILENO); |
| 30 | close(resultPipefd[1]); |
| 31 | } |
Kevin Tung | a2eb951 | 2025-05-05 18:28:56 +0800 | [diff] [blame] | 32 | |
| 33 | int exitCode = std::system(cmd.c_str()); |
Kevin Tung | c538727 | 2025-07-28 18:10:43 +0800 | [diff] [blame] | 34 | ssize_t status = write(exitPipefd[1], &exitCode, sizeof(exitCode)); |
Kevin Tung | a2eb951 | 2025-05-05 18:28:56 +0800 | [diff] [blame] | 35 | |
Kevin Tung | c538727 | 2025-07-28 18:10:43 +0800 | [diff] [blame] | 36 | close(exitPipefd[1]); |
Kevin Tung | a2eb951 | 2025-05-05 18:28:56 +0800 | [diff] [blame] | 37 | _exit((status == sizeof(exitCode)) ? 0 : 1); |
| 38 | } |
| 39 | else if (pid > 0) |
| 40 | { |
Kevin Tung | c538727 | 2025-07-28 18:10:43 +0800 | [diff] [blame] | 41 | close(exitPipefd[1]); |
Kevin Tung | a2eb951 | 2025-05-05 18:28:56 +0800 | [diff] [blame] | 42 | |
Kevin Tung | c538727 | 2025-07-28 18:10:43 +0800 | [diff] [blame] | 43 | if (result) |
| 44 | { |
| 45 | close(resultPipefd[1]); |
| 46 | } |
| 47 | |
| 48 | auto fdio = |
| 49 | std::make_unique<sdbusplus::async::fdio>(ctx, exitPipefd[0]); |
Kevin Tung | a2eb951 | 2025-05-05 18:28:56 +0800 | [diff] [blame] | 50 | |
| 51 | if (!fdio) |
| 52 | { |
| 53 | error("Failed to create fdio for command: {CMD}", "CMD", cmd); |
Kevin Tung | c538727 | 2025-07-28 18:10:43 +0800 | [diff] [blame] | 54 | close(exitPipefd[0]); |
Kevin Tung | a2eb951 | 2025-05-05 18:28:56 +0800 | [diff] [blame] | 55 | co_return false; |
| 56 | } |
| 57 | |
| 58 | co_await fdio->next(); |
| 59 | |
Kevin Tung | c538727 | 2025-07-28 18:10:43 +0800 | [diff] [blame] | 60 | if (result) |
| 61 | { |
| 62 | auto& resStr = result->get(); |
| 63 | resStr.clear(); |
| 64 | char buffer[1024]; |
| 65 | ssize_t n; |
| 66 | while ((n = read(resultPipefd[0], buffer, sizeof(buffer))) > 0) |
| 67 | { |
| 68 | resStr.append(buffer, n); |
| 69 | } |
| 70 | close(resultPipefd[0]); |
| 71 | } |
| 72 | |
Kevin Tung | a2eb951 | 2025-05-05 18:28:56 +0800 | [diff] [blame] | 73 | int exitCode = -1; |
Kevin Tung | c538727 | 2025-07-28 18:10:43 +0800 | [diff] [blame] | 74 | ssize_t bytesRead = read(exitPipefd[0], &exitCode, sizeof(exitCode)); |
| 75 | close(exitPipefd[0]); |
Kevin Tung | a2eb951 | 2025-05-05 18:28:56 +0800 | [diff] [blame] | 76 | |
| 77 | if (bytesRead != sizeof(exitCode)) |
| 78 | { |
| 79 | error("Failed to read exit code from command {CMD}", "CMD", cmd); |
| 80 | co_return false; |
| 81 | } |
| 82 | |
| 83 | int status; |
| 84 | if (waitpid(pid, &status, 0) < 0) |
| 85 | { |
| 86 | error("waitpid failed for PID {PID} for command {CMD}", "PID", pid, |
| 87 | "CMD", cmd); |
| 88 | co_return false; |
| 89 | } |
| 90 | |
| 91 | if (exitCode != 0) |
| 92 | { |
| 93 | error("Command {CMD} exited with code {CODE}", "CMD", cmd, "CODE", |
| 94 | exitCode); |
| 95 | co_return false; |
| 96 | } |
| 97 | |
| 98 | debug("{CMD} executed successfully", "CMD", cmd); |
| 99 | |
| 100 | co_return true; |
| 101 | } |
| 102 | else |
| 103 | { |
| 104 | error("Fork failed for command: {CMD}", "CMD", cmd); |
Kevin Tung | c538727 | 2025-07-28 18:10:43 +0800 | [diff] [blame] | 105 | close(exitPipefd[0]); |
| 106 | close(exitPipefd[1]); |
| 107 | if (result) |
| 108 | { |
| 109 | close(resultPipefd[0]); |
| 110 | close(resultPipefd[1]); |
| 111 | } |
Kevin Tung | a2eb951 | 2025-05-05 18:28:56 +0800 | [diff] [blame] | 112 | co_return false; |
| 113 | } |
| 114 | } |