1 //===- Win32/Program.cpp - Win32 Program Implementation ------- -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file provides the Win32 specific implementation of the Program class.
12 //===----------------------------------------------------------------------===//
20 //===----------------------------------------------------------------------===//
21 //=== WARNING: Implementation here must contain only Win32 specific code
22 //=== and must not be UNIX code
23 //===----------------------------------------------------------------------===//
26 struct Win32ProcessInfo {
35 Program::Program() : Data_(0) {}
39 Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
40 CloseHandle(wpi->hProcess);
46 // This function just uses the PATH environment variable to find the program.
48 Program::FindProgramByName(const std::string& progName) {
50 // Check some degenerate cases
51 if (progName.length() == 0) // no program
54 if (!temp.set(progName)) // invalid name
56 // Return paths with slashes verbatim.
57 if (progName.find('\\') != std::string::npos ||
58 progName.find('/') != std::string::npos)
61 // At this point, the file name is valid and does not contain slashes.
62 // Let Windows search for it.
63 char buffer[MAX_PATH];
65 DWORD len = SearchPath(NULL, progName.c_str(), ".exe", MAX_PATH,
68 // See if it wasn't found.
72 // See if we got the entire path.
76 // Buffer was too small; grow and retry.
78 char *b = reinterpret_cast<char *>(_alloca(len+1));
79 DWORD len2 = SearchPath(NULL, progName.c_str(), ".exe", len+1, b, &dummy);
81 // It is unlikely the search failed, but it's always possible some file
82 // was added or removed since the last search, so be paranoid...
92 static HANDLE RedirectIO(const Path *path, int fd, std::string* ErrMsg) {
95 DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fd),
96 GetCurrentProcess(), &h,
97 0, TRUE, DUPLICATE_SAME_ACCESS);
105 fname = path->c_str();
107 SECURITY_ATTRIBUTES sa;
108 sa.nLength = sizeof(sa);
109 sa.lpSecurityDescriptor = 0;
110 sa.bInheritHandle = TRUE;
112 h = CreateFile(fname, fd ? GENERIC_WRITE : GENERIC_READ, FILE_SHARE_READ,
113 &sa, fd == 0 ? OPEN_EXISTING : CREATE_ALWAYS,
114 FILE_ATTRIBUTE_NORMAL, NULL);
115 if (h == INVALID_HANDLE_VALUE) {
116 MakeErrMsg(ErrMsg, std::string(fname) + ": Can't open file for " +
117 (fd ? "input: " : "output: "));
123 /// ArgNeedsQuotes - Check whether argument needs to be quoted when calling
125 static bool ArgNeedsQuotes(const char *Str) {
126 return Str[0] == '\0' || strpbrk(Str, "\t \"&\'()*<>\\`^|") != 0;
129 /// CountPrecedingBackslashes - Returns the number of backslashes preceding Cur
130 /// in the C string Start.
131 static unsigned int CountPrecedingBackslashes(const char *Start,
133 unsigned int Count = 0;
135 while (Cur >= Start && *Cur == '\\') {
142 /// EscapePrecedingEscapes - Append a backslash to Dst for every backslash
143 /// preceding Cur in the Start string. Assumes Dst has enough space.
144 static char *EscapePrecedingEscapes(char *Dst, const char *Start,
146 unsigned PrecedingEscapes = CountPrecedingBackslashes(Start, Cur);
147 while (PrecedingEscapes > 0) {
154 /// ArgLenWithQuotes - Check whether argument needs to be quoted when calling
155 /// CreateProcess and returns length of quoted arg with escaped quotes
156 static unsigned int ArgLenWithQuotes(const char *Str) {
157 const char *Start = Str;
158 bool Quoted = ArgNeedsQuotes(Str);
159 unsigned int len = Quoted ? 2 : 0;
161 while (*Str != '\0') {
163 // We need to add a backslash, but ensure that it isn't escaped.
164 unsigned PrecedingEscapes = CountPrecedingBackslashes(Start, Str);
165 len += PrecedingEscapes + 1;
167 // Note that we *don't* need to escape runs of backslashes that don't
168 // precede a double quote! See MSDN:
169 // http://msdn.microsoft.com/en-us/library/17w5ykft%28v=vs.85%29.aspx
176 // Make sure the closing quote doesn't get escaped by a trailing backslash.
177 unsigned PrecedingEscapes = CountPrecedingBackslashes(Start, Str);
178 len += PrecedingEscapes + 1;
186 Program::Execute(const Path& path,
189 const Path** redirects,
190 unsigned memoryLimit,
191 std::string* ErrMsg) {
193 Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
194 CloseHandle(wpi->hProcess);
199 if (!path.canExecute()) {
201 *ErrMsg = "program not executable";
205 // Windows wants a command line, not an array of args, to pass to the new
206 // process. We have to concatenate them all, while quoting the args that
207 // have embedded spaces (or are empty).
209 // First, determine the length of the command line.
211 for (unsigned i = 0; args[i]; i++) {
212 len += ArgLenWithQuotes(args[i]) + 1;
215 // Now build the command line.
216 char *command = reinterpret_cast<char *>(_alloca(len+1));
219 for (unsigned i = 0; args[i]; i++) {
220 const char *arg = args[i];
221 const char *start = arg;
223 bool needsQuoting = ArgNeedsQuotes(arg);
227 while (*arg != '\0') {
229 // Escape all preceding escapes (if any), and then escape the quote.
230 p = EscapePrecedingEscapes(p, start, arg);
238 // Make sure our quote doesn't get escaped by a trailing backslash.
239 p = EscapePrecedingEscapes(p, start, arg);
247 // The pointer to the environment block for the new process.
251 // An environment block consists of a null-terminated block of
252 // null-terminated strings. Convert the array of environment variables to
253 // an environment block by concatenating them.
255 // First, determine the length of the environment block.
257 for (unsigned i = 0; envp[i]; i++)
258 len += strlen(envp[i]) + 1;
260 // Now build the environment block.
261 envblock = reinterpret_cast<char *>(_alloca(len+1));
264 for (unsigned i = 0; envp[i]; i++) {
265 const char *ev = envp[i];
266 size_t len = strlen(ev) + 1;
274 // Create a child process.
276 memset(&si, 0, sizeof(si));
278 si.hStdInput = INVALID_HANDLE_VALUE;
279 si.hStdOutput = INVALID_HANDLE_VALUE;
280 si.hStdError = INVALID_HANDLE_VALUE;
283 si.dwFlags = STARTF_USESTDHANDLES;
285 si.hStdInput = RedirectIO(redirects[0], 0, ErrMsg);
286 if (si.hStdInput == INVALID_HANDLE_VALUE) {
287 MakeErrMsg(ErrMsg, "can't redirect stdin");
290 si.hStdOutput = RedirectIO(redirects[1], 1, ErrMsg);
291 if (si.hStdOutput == INVALID_HANDLE_VALUE) {
292 CloseHandle(si.hStdInput);
293 MakeErrMsg(ErrMsg, "can't redirect stdout");
296 if (redirects[1] && redirects[2] && *(redirects[1]) == *(redirects[2])) {
297 // If stdout and stderr should go to the same place, redirect stderr
298 // to the handle already open for stdout.
299 DuplicateHandle(GetCurrentProcess(), si.hStdOutput,
300 GetCurrentProcess(), &si.hStdError,
301 0, TRUE, DUPLICATE_SAME_ACCESS);
303 // Just redirect stderr
304 si.hStdError = RedirectIO(redirects[2], 2, ErrMsg);
305 if (si.hStdError == INVALID_HANDLE_VALUE) {
306 CloseHandle(si.hStdInput);
307 CloseHandle(si.hStdOutput);
308 MakeErrMsg(ErrMsg, "can't redirect stderr");
314 PROCESS_INFORMATION pi;
315 memset(&pi, 0, sizeof(pi));
319 BOOL rc = CreateProcess(path.c_str(), command, NULL, NULL, TRUE, 0,
320 envblock, NULL, &si, &pi);
321 DWORD err = GetLastError();
323 // Regardless of whether the process got created or not, we are done with
324 // the handles we created for it to inherit.
325 CloseHandle(si.hStdInput);
326 CloseHandle(si.hStdOutput);
327 CloseHandle(si.hStdError);
329 // Now return an error if the process didn't get created.
332 MakeErrMsg(ErrMsg, std::string("Couldn't execute program '") +
336 Win32ProcessInfo* wpi = new Win32ProcessInfo;
337 wpi->hProcess = pi.hProcess;
338 wpi->dwProcessId = pi.dwProcessId;
341 // Make sure these get closed no matter what.
342 ScopedCommonHandle hThread(pi.hThread);
344 // Assign the process to a job if a memory limit is defined.
345 ScopedJobHandle hJob;
346 if (memoryLimit != 0) {
347 hJob = CreateJobObject(0, 0);
348 bool success = false;
350 JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli;
351 memset(&jeli, 0, sizeof(jeli));
352 jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY;
353 jeli.ProcessMemoryLimit = uintptr_t(memoryLimit) * 1048576;
354 if (SetInformationJobObject(hJob, JobObjectExtendedLimitInformation,
355 &jeli, sizeof(jeli))) {
356 if (AssignProcessToJobObject(hJob, pi.hProcess))
361 SetLastError(GetLastError());
362 MakeErrMsg(ErrMsg, std::string("Unable to set memory limit"));
363 TerminateProcess(pi.hProcess, 1);
364 WaitForSingleObject(pi.hProcess, INFINITE);
373 Program::Wait(const Path &path,
374 unsigned secondsToWait,
375 std::string* ErrMsg) {
377 MakeErrMsg(ErrMsg, "Process not started!");
381 Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
382 HANDLE hProcess = wpi->hProcess;
384 // Wait for the process to terminate.
385 DWORD millisecondsToWait = INFINITE;
386 if (secondsToWait > 0)
387 millisecondsToWait = secondsToWait * 1000;
389 if (WaitForSingleObject(hProcess, millisecondsToWait) == WAIT_TIMEOUT) {
390 if (!TerminateProcess(hProcess, 1)) {
391 MakeErrMsg(ErrMsg, "Failed to terminate timed-out program.");
392 // -2 indicates a crash or timeout as opposed to failure to execute.
395 WaitForSingleObject(hProcess, INFINITE);
398 // Get its exit status.
400 BOOL rc = GetExitCodeProcess(hProcess, &status);
401 DWORD err = GetLastError();
405 MakeErrMsg(ErrMsg, "Failed getting status for program.");
406 // -2 indicates a crash or timeout as opposed to failure to execute.
413 // Pass 10(Warning) and 11(Error) to the callee as negative value.
414 if ((status & 0xBFFF0000U) == 0x80000000U)
418 return status & 0x7FFFFFFF;
423 error_code Program::ChangeStdinToBinary(){
424 int result = _setmode( _fileno(stdin), _O_BINARY );
426 return error_code(errno, generic_category());
427 return make_error_code(errc::success);
430 error_code Program::ChangeStdoutToBinary(){
431 int result = _setmode( _fileno(stdout), _O_BINARY );
433 return error_code(errno, generic_category());
434 return make_error_code(errc::success);
437 error_code Program::ChangeStderrToBinary(){
438 int result = _setmode( _fileno(stderr), _O_BINARY );
440 return error_code(errno, generic_category());
441 return make_error_code(errc::success);
444 bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef<const char*> Args) {
445 // The documented max length of the command line passed to CreateProcess.
446 static const size_t MaxCommandStringLength = 32768;
447 size_t ArgLength = 0;
448 for (ArrayRef<const char*>::iterator I = Args.begin(), E = Args.end();
450 // Account for the trailing space for every arg but the last one and the
451 // trailing NULL of the last argument.
452 ArgLength += ArgLenWithQuotes(*I) + 1;
453 if (ArgLength > MaxCommandStringLength) {