| #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 <memory> |
| #include <string> |
| |
| #include "absl/log/log.h" |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| #include "tlbmc/utils/command_executor.h" |
| |
| namespace milotic_tlbmc { |
| |
| class ShellExecutor : public CommandExecutor { |
| public: |
| absl::StatusOr<std::string> Execute( |
| const std::string& command) const override { |
| std::unique_ptr<FILE, FileDeleter> pipe_fp(popen(command.c_str(), "r"), |
| pclose_deleter_); |
| 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.get()) != nullptr) { |
| result += buffer.data(); |
| } |
| return result; |
| } |
| |
| private: |
| using FileDeleter = void (*)(FILE*); |
| |
| FileDeleter pclose_deleter_ = [](FILE* fp) { |
| if (fp == nullptr) { |
| LOG(ERROR) << "File handle already closed before attempting to close!"; |
| return; |
| } |
| if (pclose(fp)) { |
| LOG(ERROR) << "Failed to close file handle!"; |
| } |
| }; |
| }; |
| |
| } // namespace milotic_tlbmc |
| |
| #endif // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_UTILS_SHELL_COMMAND_EXECUTOR_H_ |