| #ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_UTILS_SHELL_COMMAND_EXECUTOR_H_ |
| #define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_UTILS_SHELL_COMMAND_EXECUTOR_H_ |
| |
| #include <array> |
| #include <cstdio> |
| #include <string> |
| |
| #include "absl/log/log.h" |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| #include "absl/strings/str_format.h" |
| #include "tlbmc/utils/command_executor.h" |
| |
| namespace milotic_tlbmc { |
| |
| class ShellExecutor : public CommandExecutor { |
| public: |
| absl::StatusOr<std::string> Execute(const std::string& command, |
| bool ignore_error) const override { |
| // We want stderr to be captured as well |
| std::string full_command = command + " 2>&1"; |
| |
| FILE* pipe_fp(popen(full_command.c_str(), "r")); |
| if (pipe_fp == nullptr) { |
| LOG(ERROR) << "popen() failed for command: " << command; |
| return absl::UnavailableError("popen() failed!"); |
| } |
| |
| std::array<char, 4096> buffer; |
| std::string result; |
| while (fgets(buffer.data(), buffer.size(), pipe_fp) != nullptr) { |
| result += buffer.data(); |
| } |
| |
| int exit_code = pclose(pipe_fp); |
| if (exit_code != 0 && !ignore_error) { |
| return absl::InternalError( |
| absl::StrFormat("Command %s failed with exit code: %d and output: %s", |
| command, exit_code, result)); |
| } |
| return result; |
| } |
| }; |
| |
| } // namespace milotic_tlbmc |
| |
| #endif // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_UTILS_SHELL_COMMAND_EXECUTOR_H_ |