2015-11-03 21:20:15 +01:00
|
|
|
#include "subprocess.h"
|
|
|
|
#include <cstdio>
|
|
|
|
#include <stdexcept>
|
2018-05-19 16:45:56 +02:00
|
|
|
|
|
|
|
#if !defined(_MSC_VER)
|
2015-11-28 17:06:54 +01:00
|
|
|
#include <sys/wait.h>
|
2018-05-19 16:45:56 +02:00
|
|
|
constexpr const char* openmode = "re";
|
|
|
|
#else
|
|
|
|
#define popen _popen
|
|
|
|
#define pclose _pclose
|
|
|
|
#define WEXITSTATUS(a) a
|
|
|
|
constexpr const char* openmode = "r";
|
|
|
|
#endif
|
2015-11-03 21:20:15 +01:00
|
|
|
|
|
|
|
using std::string;
|
|
|
|
|
|
|
|
namespace cpputils {
|
2015-11-03 22:11:09 +01:00
|
|
|
//TODO Exception safety
|
|
|
|
|
2015-11-03 21:20:15 +01:00
|
|
|
string Subprocess::call(const string &command) {
|
2015-11-03 22:11:09 +01:00
|
|
|
FILE *subprocessOutput = _call(command);
|
2015-11-03 21:20:15 +01:00
|
|
|
|
|
|
|
string result;
|
|
|
|
char buffer[1024];
|
2015-11-07 09:11:12 +01:00
|
|
|
while(fgets(buffer, sizeof(buffer), subprocessOutput) != nullptr) {
|
2015-11-03 21:20:15 +01:00
|
|
|
result += buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto returncode = pclose(subprocessOutput);
|
|
|
|
if(WEXITSTATUS(returncode) != 0) {
|
|
|
|
throw std::runtime_error("Subprocess \""+command+"\" exited with code "+std::to_string(WEXITSTATUS(returncode)));
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2015-11-03 22:11:09 +01:00
|
|
|
|
|
|
|
int Subprocess::callAndGetReturnCode(const string &command) {
|
|
|
|
FILE *subprocess = _call(command);
|
|
|
|
|
|
|
|
auto returncode = pclose(subprocess);
|
|
|
|
return WEXITSTATUS(returncode);
|
|
|
|
}
|
|
|
|
|
|
|
|
FILE *Subprocess::_call(const string &command) {
|
2018-05-19 16:45:56 +02:00
|
|
|
FILE *subprocess = popen(command.c_str(), openmode);
|
2015-11-03 22:11:09 +01:00
|
|
|
if (!subprocess)
|
|
|
|
{
|
|
|
|
throw std::runtime_error("Error starting subprocess "+command);
|
|
|
|
}
|
|
|
|
return subprocess;
|
|
|
|
}
|
2015-11-07 09:11:12 +01:00
|
|
|
}
|