blob: 96414271e75208039b15a8748e4baab90f52cfc4 [file] [log] [blame]
#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_