summaryrefslogtreecommitdiffstats
path: root/src/Utils.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/Utils.cxx')
-rw-r--r--src/Utils.cxx101
1 files changed, 48 insertions, 53 deletions
diff --git a/src/Utils.cxx b/src/Utils.cxx
index 160e13c..be5e7b1 100644
--- a/src/Utils.cxx
+++ b/src/Utils.cxx
@@ -17,11 +17,12 @@
#include "Utils.h"
#include "Version.h"
-#include <cxsys/Process.h>
#include <fstream>
#include <llvm/ADT/SmallString.h>
#include <llvm/Support/FileSystem.h>
#include <llvm/Support/Path.h>
+#include <llvm/Support/Program.h>
+#include <system_error>
#include <vector>
static std::string castxmlResourceDir;
@@ -109,64 +110,58 @@ unsigned int getVersionValue()
bool runCommand(int argc, const char* const* argv, int& ret, std::string& out,
std::string& err, std::string& msg)
{
- std::vector<const char*> cmd(argv, argv + argc);
- cmd.push_back(0);
- ret = 1;
- out = "";
- err = "";
- std::vector<char> outBuf;
- std::vector<char> errBuf;
-
- cxsysProcess* cp = cxsysProcess_New();
- cxsysProcess_SetCommand(cp, &*cmd.begin());
- cxsysProcess_SetOption(cp, cxsysProcess_Option_HideWindow, 1);
-#ifdef _WIN32
- cxsysProcess_SetPipeFile(cp, cxsysProcess_Pipe_STDIN, "//./nul");
-#else
- cxsysProcess_SetPipeFile(cp, cxsysProcess_Pipe_STDIN, "/dev/null");
-#endif
- cxsysProcess_Execute(cp);
-
- char* data;
- int length;
- int pipe;
- while ((pipe = cxsysProcess_WaitForData(cp, &data, &length, 0)) > 0) {
- if (pipe == cxsysProcess_Pipe_STDOUT) {
- outBuf.insert(outBuf.end(), data, data + length);
- } else if (pipe == cxsysProcess_Pipe_STDERR) {
- errBuf.insert(errBuf.end(), data, data + length);
- }
+ // Find the program to run.
+ llvm::ErrorOr<std::string> maybeProg = llvm::sys::findProgramByName(argv[0]);
+ if (std::error_code e = maybeProg.getError()) {
+ msg = e.message();
+ return false;
}
+ std::string const& prog = *maybeProg;
- cxsysProcess_WaitForExit(cp, 0);
- if (!outBuf.empty()) {
- out.append(&*outBuf.begin(), outBuf.size());
- }
- if (!errBuf.empty()) {
- err.append(&*errBuf.begin(), errBuf.size());
+ // Create a temporary directory to hold output files.
+ llvm::SmallString<128> tmpDir;
+ if (std::error_code e =
+ llvm::sys::fs::createUniqueDirectory("castxml", tmpDir)) {
+ msg = e.message();
+ return false;
}
+ llvm::SmallString<128> tmpOut = tmpDir;
+ tmpOut.append("out");
+ llvm::SmallString<128> tmpErr = tmpDir;
+ tmpErr.append("err");
+
+ // Construct file redirects.
+ llvm::StringRef inFile; // empty means /dev/null
+ llvm::StringRef outFile = tmpOut.str();
+ llvm::StringRef errFile = tmpErr.str();
+ llvm::StringRef const* redirects[3];
+ redirects[0] = &inFile;
+ redirects[1] = &outFile;
+ redirects[2] = &errFile;
- bool result = true;
- switch (cxsysProcess_GetState(cp)) {
- case cxsysProcess_State_Exited:
- ret = cxsysProcess_GetExitValue(cp);
- break;
- case cxsysProcess_State_Exception:
- msg = cxsysProcess_GetExceptionString(cp);
- result = false;
- break;
- case cxsysProcess_State_Error:
- msg = cxsysProcess_GetErrorString(cp);
- result = false;
- break;
- default:
- msg = "Process terminated in unexpected state.\n";
- result = false;
- break;
+ std::vector<const char*> cmd(argv, argv + argc);
+ cmd.push_back(0);
+
+ // Actually run the command.
+ ret = llvm::sys::ExecuteAndWait(prog, &*cmd.begin(), nullptr, redirects,
+ 0, 0, &msg, nullptr);
+
+ // Load the output from the temporary files.
+ {
+ std::ifstream fout(outFile.str());
+ std::ifstream ferr(errFile.str());
+ out.assign(std::istreambuf_iterator<char>(fout),
+ std::istreambuf_iterator<char>());
+ err.assign(std::istreambuf_iterator<char>(ferr),
+ std::istreambuf_iterator<char>());
}
- cxsysProcess_Delete(cp);
- return result;
+ // Remove temporary files and directory.
+ llvm::sys::fs::remove(llvm::Twine(tmpOut));
+ llvm::sys::fs::remove(llvm::Twine(tmpErr));
+ llvm::sys::fs::remove(llvm::Twine(tmpDir));
+
+ return ret >= 0;
}
std::string encodeXML(std::string const& in, bool cdata)