xref: /openbmc/phosphor-bmc-code-mgmt/common/src/utils.cpp (revision a2eb951f7384c2b4fa494f90e78295f615c12a56)
1 #include "common/include/utils.hpp"
2 
3 #include <phosphor-logging/lg2.hpp>
4 
5 PHOSPHOR_LOG2_USING;
6 
7 sdbusplus::async::task<bool> asyncSystem(sdbusplus::async::context& ctx,
8                                          const std::string& cmd)
9 {
10     int pipefd[2];
11     if (pipe(pipefd) == -1)
12     {
13         error("Failed to create pipe for command: {CMD}", "CMD", cmd);
14         co_return false;
15     }
16 
17     pid_t pid = fork();
18     if (pid == 0)
19     {
20         close(pipefd[0]);
21 
22         int exitCode = std::system(cmd.c_str());
23         ssize_t status = write(pipefd[1], &exitCode, sizeof(exitCode));
24 
25         close(pipefd[1]);
26         _exit((status == sizeof(exitCode)) ? 0 : 1);
27     }
28     else if (pid > 0)
29     {
30         close(pipefd[1]);
31 
32         auto fdio = std::make_unique<sdbusplus::async::fdio>(ctx, pipefd[0]);
33 
34         if (!fdio)
35         {
36             error("Failed to create fdio for command: {CMD}", "CMD", cmd);
37             close(pipefd[0]);
38             co_return false;
39         }
40 
41         co_await fdio->next();
42 
43         int exitCode = -1;
44         ssize_t bytesRead = read(pipefd[0], &exitCode, sizeof(exitCode));
45         close(pipefd[0]);
46 
47         if (bytesRead != sizeof(exitCode))
48         {
49             error("Failed to read exit code from command {CMD}", "CMD", cmd);
50             co_return false;
51         }
52 
53         int status;
54         if (waitpid(pid, &status, 0) < 0)
55         {
56             error("waitpid failed for PID {PID} for command {CMD}", "PID", pid,
57                   "CMD", cmd);
58             co_return false;
59         }
60 
61         if (exitCode != 0)
62         {
63             error("Command {CMD} exited with code {CODE}", "CMD", cmd, "CODE",
64                   exitCode);
65             co_return false;
66         }
67 
68         debug("{CMD} executed successfully", "CMD", cmd);
69 
70         co_return true;
71     }
72     else
73     {
74         error("Fork failed for command: {CMD}", "CMD", cmd);
75         close(pipefd[0]);
76         close(pipefd[1]);
77         co_return false;
78     }
79 }
80