common: move asyncSystem() to common
asyncSystem() is shared across updaters, so moved to common.
Change-Id: I3545d34ecc1f1bf8a226d020267ae00bcf42c5f9
Signed-off-by: Kevin Tung <Kevin.Tung@quantatw.com>
diff --git a/common/src/utils.cpp b/common/src/utils.cpp
new file mode 100644
index 0000000..683ca84
--- /dev/null
+++ b/common/src/utils.cpp
@@ -0,0 +1,79 @@
+#include "common/include/utils.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+PHOSPHOR_LOG2_USING;
+
+sdbusplus::async::task<bool> asyncSystem(sdbusplus::async::context& ctx,
+ const std::string& cmd)
+{
+ int pipefd[2];
+ if (pipe(pipefd) == -1)
+ {
+ error("Failed to create pipe for command: {CMD}", "CMD", cmd);
+ co_return false;
+ }
+
+ pid_t pid = fork();
+ if (pid == 0)
+ {
+ close(pipefd[0]);
+
+ int exitCode = std::system(cmd.c_str());
+ ssize_t status = write(pipefd[1], &exitCode, sizeof(exitCode));
+
+ close(pipefd[1]);
+ _exit((status == sizeof(exitCode)) ? 0 : 1);
+ }
+ else if (pid > 0)
+ {
+ close(pipefd[1]);
+
+ auto fdio = std::make_unique<sdbusplus::async::fdio>(ctx, pipefd[0]);
+
+ if (!fdio)
+ {
+ error("Failed to create fdio for command: {CMD}", "CMD", cmd);
+ close(pipefd[0]);
+ co_return false;
+ }
+
+ co_await fdio->next();
+
+ int exitCode = -1;
+ ssize_t bytesRead = read(pipefd[0], &exitCode, sizeof(exitCode));
+ close(pipefd[0]);
+
+ if (bytesRead != sizeof(exitCode))
+ {
+ error("Failed to read exit code from command {CMD}", "CMD", cmd);
+ co_return false;
+ }
+
+ int status;
+ if (waitpid(pid, &status, 0) < 0)
+ {
+ error("waitpid failed for PID {PID} for command {CMD}", "PID", pid,
+ "CMD", cmd);
+ co_return false;
+ }
+
+ if (exitCode != 0)
+ {
+ error("Command {CMD} exited with code {CODE}", "CMD", cmd, "CODE",
+ exitCode);
+ co_return false;
+ }
+
+ debug("{CMD} executed successfully", "CMD", cmd);
+
+ co_return true;
+ }
+ else
+ {
+ error("Fork failed for command: {CMD}", "CMD", cmd);
+ close(pipefd[0]);
+ close(pipefd[1]);
+ co_return false;
+ }
+}