//=== and must not be UNIX code
//===----------------------------------------------------------------------===//
+#ifdef __MINGW32__
+// Ancient mingw32's w32api might not have this declaration.
+extern "C"
+BOOL WINAPI SetInformationJobObject(HANDLE hJob,
+ JOBOBJECTINFOCLASS JobObjectInfoClass,
+ LPVOID lpJobObjectInfo,
+ DWORD cbJobObjectInfoLength);
+#endif
+
+namespace {
+ struct Win32ProcessInfo {
+ HANDLE hProcess;
+ DWORD dwProcessId;
+ };
+}
+
namespace llvm {
using namespace sys;
Program::~Program() {
if (Data_) {
- HANDLE hProcess = reinterpret_cast<HANDLE>(Data_);
- CloseHandle(hProcess);
+ Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
+ CloseHandle(wpi->hProcess);
+ delete wpi;
Data_ = 0;
}
}
unsigned Program::GetPid() const {
- HANDLE hProcess = reinterpret_cast<HANDLE>(Data_);
- return GetProcessId(hProcess);
+ Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
+ return wpi->dwProcessId;
}
// This function just uses the PATH environment variable to find the program.
Path temp;
if (!temp.set(progName)) // invalid name
return Path();
- if (temp.canExecute()) // already executable as is
+ // Return paths with slashes verbatim.
+ if (progName.find('\\') != std::string::npos ||
+ progName.find('/') != std::string::npos)
return temp;
- // At this point, the file name is valid and its not executable.
+ // At this point, the file name is valid and does not contain slashes.
// Let Windows search for it.
char buffer[MAX_PATH];
char *dummy = NULL;
return h;
}
-#ifdef __MINGW32__
- // Due to unknown reason, mingw32's w32api doesn't have this declaration.
- extern "C"
- BOOL WINAPI SetInformationJobObject(HANDLE hJob,
- JOBOBJECTINFOCLASS JobObjectInfoClass,
- LPVOID lpJobObjectInfo,
- DWORD cbJobObjectInfoLength);
-#endif
-
/// ArgNeedsQuotes - Check whether argument needs to be quoted when calling
/// CreateProcess.
static bool ArgNeedsQuotes(const char *Str) {
return Str[0] == '\0' || strchr(Str, ' ') != 0;
}
+
+/// ArgLenWithQuotes - Check whether argument needs to be quoted when calling
+/// CreateProcess and returns length of quoted arg with escaped quotes
+static unsigned int ArgLenWithQuotes(const char *Str) {
+ unsigned int len = ArgNeedsQuotes(Str) ? 2 : 0;
+
+ while (*Str != '\0') {
+ if (*Str == '\"')
+ ++len;
+
+ ++len;
+ ++Str;
+ }
+
+ return len;
+}
+
+
bool
Program::Execute(const Path& path,
const char** args,
unsigned memoryLimit,
std::string* ErrMsg) {
if (Data_) {
- HANDLE hProcess = reinterpret_cast<HANDLE>(Data_);
- CloseHandle(Data_);
+ Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
+ CloseHandle(wpi->hProcess);
+ delete wpi;
Data_ = 0;
}
// First, determine the length of the command line.
unsigned len = 0;
for (unsigned i = 0; args[i]; i++) {
- len += strlen(args[i]) + 1;
- if (ArgNeedsQuotes(args[i]))
- len += 2;
+ len += ArgLenWithQuotes(args[i]) + 1;
}
// Now build the command line.
for (unsigned i = 0; args[i]; i++) {
const char *arg = args[i];
- size_t len = strlen(arg);
+
bool needsQuoting = ArgNeedsQuotes(arg);
if (needsQuoting)
*p++ = '"';
- memcpy(p, arg, len);
- p += len;
+
+ while (*arg != '\0') {
+ if (*arg == '\"')
+ *p++ = '\\';
+
+ *p++ = *arg++;
+ }
+
if (needsQuoting)
*p++ = '"';
*p++ = ' ';
path.str() + "'");
return false;
}
- Data_ = reinterpret_cast<void*>(pi.hProcess);
+ Win32ProcessInfo* wpi = new Win32ProcessInfo;
+ wpi->hProcess = pi.hProcess;
+ wpi->dwProcessId = pi.dwProcessId;
+ Data_ = wpi;
// Make sure these get closed no matter what.
AutoHandle hThread(pi.hThread);
}
int
-Program::Wait(unsigned secondsToWait,
+Program::Wait(const Path &path,
+ unsigned secondsToWait,
std::string* ErrMsg) {
if (Data_ == 0) {
MakeErrMsg(ErrMsg, "Process not started!");
return -1;
}
- HANDLE hProcess = reinterpret_cast<HANDLE>(Data_);
+ Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
+ HANDLE hProcess = wpi->hProcess;
// Wait for the process to terminate.
DWORD millisecondsToWait = INFINITE;
return true;
}
- HANDLE hProcess = reinterpret_cast<HANDLE>(Data_);
+ Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
+ HANDLE hProcess = wpi->hProcess;
if (TerminateProcess(hProcess, 1) == 0) {
MakeErrMsg(ErrMsg, "The process couldn't be killed!");
return true;
return result == -1;
}
+bool Program::ChangeStderrToBinary(){
+ int result = _setmode( _fileno(stderr), _O_BINARY );
+ return result == -1;
+}
+
}