based on 3rd party lib (http://pstreams.sourceforge.net/)
| 17 | |
| 18 | // based on 3rd party lib (http://pstreams.sourceforge.net/) |
| 19 | int executeCommand(const std::string &cmd, const std::vector<std::string> &args, |
| 20 | std::string *pOutputStr, bool appendFromStdErr) |
| 21 | { |
| 22 | std::string cmdLine = cmd; |
| 23 | |
| 24 | for (auto it = args.begin(); it != args.end(); ++it) |
| 25 | { |
| 26 | cmdLine += " '"; |
| 27 | for (char c : *it) { |
| 28 | if (c == '\'') { |
| 29 | cmdLine += "'\\''"; |
| 30 | } else { |
| 31 | cmdLine += c; |
| 32 | } |
| 33 | } |
| 34 | cmdLine += "'"; |
| 35 | } |
| 36 | |
| 37 | if (pOutputStr) |
| 38 | { |
| 39 | pOutputStr->clear(); |
| 40 | } |
| 41 | |
| 42 | redi::ipstream proc(cmdLine, redi::pstreams::pstdout | redi::pstreams::pstderr); |
| 43 | std::string line; |
| 44 | // read child's stdout |
| 45 | while (std::getline(proc.out(), line)) |
| 46 | { |
| 47 | if (pOutputStr) |
| 48 | { |
| 49 | *pOutputStr += line + "\n"; |
| 50 | } |
| 51 | } |
| 52 | // if reading stdout stopped at EOF then reset the state: |
| 53 | if (proc.eof() && proc.fail()) |
| 54 | { |
| 55 | proc.clear(); |
| 56 | } |
| 57 | |
| 58 | if (appendFromStdErr) { |
| 59 | // read child's stderr |
| 60 | while (std::getline(proc.err(), line)) |
| 61 | { |
| 62 | if (pOutputStr) |
| 63 | { |
| 64 | *pOutputStr += line + "\n"; |
| 65 | } |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | proc.close(); |
| 70 | if (proc.rdbuf()->exited()) |
| 71 | { |
| 72 | return proc.rdbuf()->status(); |
| 73 | } |
| 74 | // The child did not exit normally (signal, stop, etc.). Callers compare the return |
| 75 | // value to 0 to decide success, so a 0 here would falsely report success. |
| 76 | return -1; |
no test coverage detected