blob: b6e5c7b4048f4913bfd4386fa1b609427d7d6922 [file]
#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_