|  | #include "utils.hpp" | 
|  |  | 
|  | #include <unistd.h> | 
|  |  | 
|  | #include <phosphor-logging/log.hpp> | 
|  |  | 
|  | namespace utils | 
|  | { | 
|  |  | 
|  | using namespace phosphor::logging; | 
|  |  | 
|  | std::string getService(sdbusplus::bus::bus& bus, const std::string& path, | 
|  | const std::string& interface) | 
|  | { | 
|  | auto method = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH, | 
|  | MAPPER_BUSNAME, "GetObject"); | 
|  |  | 
|  | method.append(path); | 
|  | method.append(std::vector<std::string>({interface})); | 
|  |  | 
|  | std::vector<std::pair<std::string, std::vector<std::string>>> response; | 
|  |  | 
|  | try | 
|  | { | 
|  | auto reply = bus.call(method); | 
|  | reply.read(response); | 
|  | if (response.empty()) | 
|  | { | 
|  | log<level::ERR>("Error in mapper response for getting service name", | 
|  | entry("PATH=%s", path.c_str()), | 
|  | entry("INTERFACE=%s", interface.c_str())); | 
|  | return std::string{}; | 
|  | } | 
|  | } | 
|  | catch (const sdbusplus::exception::SdBusError& e) | 
|  | { | 
|  | log<level::ERR>("Error in mapper method call", | 
|  | entry("ERROR=%s", e.what()), | 
|  | entry("PATH=%s", path.c_str()), | 
|  | entry("INTERFACE=%s", interface.c_str())); | 
|  | return std::string{}; | 
|  | } | 
|  | return response[0].first; | 
|  | } | 
|  |  | 
|  | void mergeFiles(std::vector<std::string>& srcFiles, std::string& dstFile) | 
|  | { | 
|  | std::ofstream outFile(dstFile, std::ios::out); | 
|  | for (auto& file : srcFiles) | 
|  | { | 
|  | std::ifstream inFile; | 
|  | inFile.open(file, std::ios_base::in); | 
|  | if (!inFile) | 
|  | { | 
|  | continue; | 
|  | } | 
|  |  | 
|  | inFile.peek(); | 
|  | if (inFile.eof()) | 
|  | { | 
|  | inFile.close(); | 
|  | continue; | 
|  | } | 
|  |  | 
|  | outFile << inFile.rdbuf(); | 
|  | inFile.close(); | 
|  | } | 
|  | outFile.close(); | 
|  | } | 
|  |  | 
|  | namespace internal | 
|  | { | 
|  |  | 
|  | /* @brief Helper function to build a string from command arguments */ | 
|  | static std::string buildCommandStr(const char* name, char** args) | 
|  | { | 
|  | std::string command = name; | 
|  | for (int i = 0; args[i]; i++) | 
|  | { | 
|  | command += " "; | 
|  | command += args[i]; | 
|  | } | 
|  | return command; | 
|  | } | 
|  |  | 
|  | int executeCmd(const char* path, char** args) | 
|  | { | 
|  | pid_t pid = fork(); | 
|  | if (pid == 0) | 
|  | { | 
|  | execv(path, args); | 
|  |  | 
|  | // execv only retruns on error | 
|  | auto error = errno; | 
|  | auto command = buildCommandStr(path, args); | 
|  | log<level::ERR>("Failed to execute command", entry("ERRNO=%d", error), | 
|  | entry("COMMAND=%s", command.c_str())); | 
|  | return -1; | 
|  | } | 
|  | else if (pid > 0) | 
|  | { | 
|  | int status; | 
|  | if (waitpid(pid, &status, 0) < 0) | 
|  | { | 
|  | auto error = errno; | 
|  | log<level::ERR>("waitpid error", entry("ERRNO=%d", error)); | 
|  | return -1; | 
|  | } | 
|  | else if (WEXITSTATUS(status) != 0) | 
|  | { | 
|  | auto command = buildCommandStr(path, args); | 
|  | log<level::ERR>("Error occurred when executing command", | 
|  | entry("STATUS=%d", status), | 
|  | entry("COMMAND=%s", command.c_str())); | 
|  | return -1; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | auto error = errno; | 
|  | log<level::ERR>("Error occurred during fork", entry("ERRNO=%d", error)); | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | } // namespace internal | 
|  |  | 
|  | } // namespace utils |