Remove the last unnecessary member variable of mapped_file_region. NFC.
[oota-llvm.git] / lib / Support / Windows / Program.inc
1 //===- Win32/Program.cpp - Win32 Program Implementation ------- -*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file provides the Win32 specific implementation of the Program class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "WindowsSupport.h"
15 #include "llvm/ADT/StringExtras.h"
16 #include "llvm/Support/ConvertUTF.h"
17 #include "llvm/Support/FileSystem.h"
18 #include "llvm/Support/raw_ostream.h"
19 #include "llvm/Support/WindowsError.h"
20 #include <cstdio>
21 #include <fcntl.h>
22 #include <io.h>
23 #include <malloc.h>
24
25 //===----------------------------------------------------------------------===//
26 //=== WARNING: Implementation here must contain only Win32 specific code
27 //===          and must not be UNIX code
28 //===----------------------------------------------------------------------===//
29
30 namespace llvm {
31 using namespace sys;
32
33 ProcessInfo::ProcessInfo() : ProcessHandle(0), Pid(0), ReturnCode(0) {}
34
35 ErrorOr<std::string> sys::findProgramByName(StringRef Name,
36                                             ArrayRef<StringRef> Paths) {
37   assert(!Name.empty() && "Must have a name!");
38
39   if (Name.find_first_of("/\\") != StringRef::npos)
40     return std::string(Name);
41
42   const wchar_t *Path = nullptr;
43   std::wstring PathStorage;
44   if (!Paths.empty()) {
45     PathStorage.reserve(Paths.size() * MAX_PATH);
46     for (unsigned i = 0; i < Paths.size(); ++i) {
47       if (i)
48         PathStorage.push_back(L';');
49       StringRef P = Paths[i];
50       SmallVector<wchar_t, MAX_PATH> TmpPath;
51       if (std::error_code EC = windows::UTF8ToUTF16(P, TmpPath))
52         return EC;
53       PathStorage.append(TmpPath.begin(), TmpPath.end());
54     }
55     Path = PathStorage.c_str();
56   }
57
58   SmallVector<wchar_t, MAX_PATH> U16Name;
59   if (std::error_code EC = windows::UTF8ToUTF16(Name, U16Name))
60     return EC;
61
62   SmallVector<StringRef, 12> PathExts;
63   PathExts.push_back("");
64   PathExts.push_back(".exe"); // FIXME: This must be in %PATHEXT%.
65   if (const char *PathExtEnv = std::getenv("PATHEXT"))
66     SplitString(PathExtEnv, PathExts, ";");
67
68   SmallVector<wchar_t, MAX_PATH> U16Result;
69   DWORD Len = MAX_PATH;
70   for (StringRef Ext : PathExts) {
71     SmallVector<wchar_t, MAX_PATH> U16Ext;
72     if (std::error_code EC = windows::UTF8ToUTF16(Ext, U16Ext))
73       return EC;
74
75     do {
76       U16Result.reserve(Len);
77       Len = ::SearchPathW(Path, c_str(U16Name),
78                           U16Ext.empty() ? nullptr : c_str(U16Ext),
79                           U16Result.capacity(), U16Result.data(), nullptr);
80     } while (Len > U16Result.capacity());
81
82     if (Len != 0)
83       break; // Found it.
84   }
85
86   if (Len == 0)
87     return mapWindowsError(::GetLastError());
88
89   U16Result.set_size(Len);
90
91   SmallVector<char, MAX_PATH> U8Result;
92   if (std::error_code EC =
93           windows::UTF16ToUTF8(U16Result.data(), U16Result.size(), U8Result))
94     return EC;
95
96   return std::string(U8Result.begin(), U8Result.end());
97 }
98
99 static HANDLE RedirectIO(const StringRef *path, int fd, std::string* ErrMsg) {
100   HANDLE h;
101   if (path == 0) {
102     if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fd),
103                          GetCurrentProcess(), &h,
104                          0, TRUE, DUPLICATE_SAME_ACCESS))
105       return INVALID_HANDLE_VALUE;
106     return h;
107   }
108
109   std::string fname;
110   if (path->empty())
111     fname = "NUL";
112   else
113     fname = *path;
114
115   SECURITY_ATTRIBUTES sa;
116   sa.nLength = sizeof(sa);
117   sa.lpSecurityDescriptor = 0;
118   sa.bInheritHandle = TRUE;
119
120   SmallVector<wchar_t, 128> fnameUnicode;
121   if (path->empty()) {
122     // Don't play long-path tricks on "NUL".
123     if (windows::UTF8ToUTF16(fname, fnameUnicode))
124       return INVALID_HANDLE_VALUE;
125   } else {
126     if (path::widenPath(fname, fnameUnicode))
127       return INVALID_HANDLE_VALUE;
128   }
129   h = CreateFileW(fnameUnicode.data(), fd ? GENERIC_WRITE : GENERIC_READ,
130                   FILE_SHARE_READ, &sa, fd == 0 ? OPEN_EXISTING : CREATE_ALWAYS,
131                   FILE_ATTRIBUTE_NORMAL, NULL);
132   if (h == INVALID_HANDLE_VALUE) {
133     MakeErrMsg(ErrMsg, fname + ": Can't open file for " +
134         (fd ? "input: " : "output: "));
135   }
136
137   return h;
138 }
139
140 /// ArgNeedsQuotes - Check whether argument needs to be quoted when calling
141 /// CreateProcess.
142 static bool ArgNeedsQuotes(const char *Str) {
143   return Str[0] == '\0' || strpbrk(Str, "\t \"&\'()*<>\\`^|") != 0;
144 }
145
146 /// CountPrecedingBackslashes - Returns the number of backslashes preceding Cur
147 /// in the C string Start.
148 static unsigned int CountPrecedingBackslashes(const char *Start,
149                                               const char *Cur) {
150   unsigned int Count = 0;
151   --Cur;
152   while (Cur >= Start && *Cur == '\\') {
153     ++Count;
154     --Cur;
155   }
156   return Count;
157 }
158
159 /// EscapePrecedingEscapes - Append a backslash to Dst for every backslash
160 /// preceding Cur in the Start string.  Assumes Dst has enough space.
161 static char *EscapePrecedingEscapes(char *Dst, const char *Start,
162                                     const char *Cur) {
163   unsigned PrecedingEscapes = CountPrecedingBackslashes(Start, Cur);
164   while (PrecedingEscapes > 0) {
165     *Dst++ = '\\';
166     --PrecedingEscapes;
167   }
168   return Dst;
169 }
170
171 /// ArgLenWithQuotes - Check whether argument needs to be quoted when calling
172 /// CreateProcess and returns length of quoted arg with escaped quotes
173 static unsigned int ArgLenWithQuotes(const char *Str) {
174   const char *Start = Str;
175   bool Quoted = ArgNeedsQuotes(Str);
176   unsigned int len = Quoted ? 2 : 0;
177
178   while (*Str != '\0') {
179     if (*Str == '\"') {
180       // We need to add a backslash, but ensure that it isn't escaped.
181       unsigned PrecedingEscapes = CountPrecedingBackslashes(Start, Str);
182       len += PrecedingEscapes + 1;
183     }
184     // Note that we *don't* need to escape runs of backslashes that don't
185     // precede a double quote!  See MSDN:
186     // http://msdn.microsoft.com/en-us/library/17w5ykft%28v=vs.85%29.aspx
187
188     ++len;
189     ++Str;
190   }
191
192   if (Quoted) {
193     // Make sure the closing quote doesn't get escaped by a trailing backslash.
194     unsigned PrecedingEscapes = CountPrecedingBackslashes(Start, Str);
195     len += PrecedingEscapes + 1;
196   }
197
198   return len;
199 }
200
201 }
202
203 static std::unique_ptr<char[]> flattenArgs(const char **args) {
204   // First, determine the length of the command line.
205   unsigned len = 0;
206   for (unsigned i = 0; args[i]; i++) {
207     len += ArgLenWithQuotes(args[i]) + 1;
208   }
209
210   // Now build the command line.
211   std::unique_ptr<char[]> command(new char[len+1]);
212   char *p = command.get();
213
214   for (unsigned i = 0; args[i]; i++) {
215     const char *arg = args[i];
216     const char *start = arg;
217
218     bool needsQuoting = ArgNeedsQuotes(arg);
219     if (needsQuoting)
220       *p++ = '"';
221
222     while (*arg != '\0') {
223       if (*arg == '\"') {
224         // Escape all preceding escapes (if any), and then escape the quote.
225         p = EscapePrecedingEscapes(p, start, arg);
226         *p++ = '\\';
227       }
228
229       *p++ = *arg++;
230     }
231
232     if (needsQuoting) {
233       // Make sure our quote doesn't get escaped by a trailing backslash.
234       p = EscapePrecedingEscapes(p, start, arg);
235       *p++ = '"';
236     }
237     *p++ = ' ';
238   }
239
240   *p = 0;
241   return command;
242 }
243
244 static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
245                     const char **envp, const StringRef **redirects,
246                     unsigned memoryLimit, std::string *ErrMsg) {
247   if (!sys::fs::can_execute(Program)) {
248     if (ErrMsg)
249       *ErrMsg = "program not executable";
250     return false;
251   }
252
253   // Windows wants a command line, not an array of args, to pass to the new
254   // process.  We have to concatenate them all, while quoting the args that
255   // have embedded spaces (or are empty).
256   std::unique_ptr<char[]> command = flattenArgs(args);
257
258   // The pointer to the environment block for the new process.
259   std::vector<wchar_t> EnvBlock;
260
261   if (envp) {
262     // An environment block consists of a null-terminated block of
263     // null-terminated strings. Convert the array of environment variables to
264     // an environment block by concatenating them.
265     for (unsigned i = 0; envp[i]; ++i) {
266       SmallVector<wchar_t, MAX_PATH> EnvString;
267       if (std::error_code ec = windows::UTF8ToUTF16(envp[i], EnvString)) {
268         SetLastError(ec.value());
269         MakeErrMsg(ErrMsg, "Unable to convert environment variable to UTF-16");
270         return false;
271       }
272
273       EnvBlock.insert(EnvBlock.end(), EnvString.begin(), EnvString.end());
274       EnvBlock.push_back(0);
275     }
276     EnvBlock.push_back(0);
277   }
278
279   // Create a child process.
280   STARTUPINFOW si;
281   memset(&si, 0, sizeof(si));
282   si.cb = sizeof(si);
283   si.hStdInput = INVALID_HANDLE_VALUE;
284   si.hStdOutput = INVALID_HANDLE_VALUE;
285   si.hStdError = INVALID_HANDLE_VALUE;
286
287   if (redirects) {
288     si.dwFlags = STARTF_USESTDHANDLES;
289
290     si.hStdInput = RedirectIO(redirects[0], 0, ErrMsg);
291     if (si.hStdInput == INVALID_HANDLE_VALUE) {
292       MakeErrMsg(ErrMsg, "can't redirect stdin");
293       return false;
294     }
295     si.hStdOutput = RedirectIO(redirects[1], 1, ErrMsg);
296     if (si.hStdOutput == INVALID_HANDLE_VALUE) {
297       CloseHandle(si.hStdInput);
298       MakeErrMsg(ErrMsg, "can't redirect stdout");
299       return false;
300     }
301     if (redirects[1] && redirects[2] && *(redirects[1]) == *(redirects[2])) {
302       // If stdout and stderr should go to the same place, redirect stderr
303       // to the handle already open for stdout.
304       if (!DuplicateHandle(GetCurrentProcess(), si.hStdOutput,
305                            GetCurrentProcess(), &si.hStdError,
306                            0, TRUE, DUPLICATE_SAME_ACCESS)) {
307         CloseHandle(si.hStdInput);
308         CloseHandle(si.hStdOutput);
309         MakeErrMsg(ErrMsg, "can't dup stderr to stdout");
310         return false;
311       }
312     } else {
313       // Just redirect stderr
314       si.hStdError = RedirectIO(redirects[2], 2, ErrMsg);
315       if (si.hStdError == INVALID_HANDLE_VALUE) {
316         CloseHandle(si.hStdInput);
317         CloseHandle(si.hStdOutput);
318         MakeErrMsg(ErrMsg, "can't redirect stderr");
319         return false;
320       }
321     }
322   }
323
324   PROCESS_INFORMATION pi;
325   memset(&pi, 0, sizeof(pi));
326
327   fflush(stdout);
328   fflush(stderr);
329
330   SmallVector<wchar_t, MAX_PATH> ProgramUtf16;
331   if (std::error_code ec = path::widenPath(Program, ProgramUtf16)) {
332     SetLastError(ec.value());
333     MakeErrMsg(ErrMsg,
334                std::string("Unable to convert application name to UTF-16"));
335     return false;
336   }
337
338   SmallVector<wchar_t, MAX_PATH> CommandUtf16;
339   if (std::error_code ec = windows::UTF8ToUTF16(command.get(), CommandUtf16)) {
340     SetLastError(ec.value());
341     MakeErrMsg(ErrMsg,
342                std::string("Unable to convert command-line to UTF-16"));
343     return false;
344   }
345
346   BOOL rc = CreateProcessW(ProgramUtf16.data(), CommandUtf16.data(), 0, 0,
347                            TRUE, CREATE_UNICODE_ENVIRONMENT,
348                            EnvBlock.empty() ? 0 : EnvBlock.data(), 0, &si,
349                            &pi);
350   DWORD err = GetLastError();
351
352   // Regardless of whether the process got created or not, we are done with
353   // the handles we created for it to inherit.
354   CloseHandle(si.hStdInput);
355   CloseHandle(si.hStdOutput);
356   CloseHandle(si.hStdError);
357
358   // Now return an error if the process didn't get created.
359   if (!rc) {
360     SetLastError(err);
361     MakeErrMsg(ErrMsg, std::string("Couldn't execute program '") +
362                Program.str() + "'");
363     return false;
364   }
365
366   PI.Pid = pi.dwProcessId;
367   PI.ProcessHandle = pi.hProcess;
368
369   // Make sure these get closed no matter what.
370   ScopedCommonHandle hThread(pi.hThread);
371
372   // Assign the process to a job if a memory limit is defined.
373   ScopedJobHandle hJob;
374   if (memoryLimit != 0) {
375     hJob = CreateJobObjectW(0, 0);
376     bool success = false;
377     if (hJob) {
378       JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli;
379       memset(&jeli, 0, sizeof(jeli));
380       jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY;
381       jeli.ProcessMemoryLimit = uintptr_t(memoryLimit) * 1048576;
382       if (SetInformationJobObject(hJob, JobObjectExtendedLimitInformation,
383                                   &jeli, sizeof(jeli))) {
384         if (AssignProcessToJobObject(hJob, pi.hProcess))
385           success = true;
386       }
387     }
388     if (!success) {
389       SetLastError(GetLastError());
390       MakeErrMsg(ErrMsg, std::string("Unable to set memory limit"));
391       TerminateProcess(pi.hProcess, 1);
392       WaitForSingleObject(pi.hProcess, INFINITE);
393       return false;
394     }
395   }
396
397   return true;
398 }
399
400 namespace llvm {
401 ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
402                       bool WaitUntilChildTerminates, std::string *ErrMsg) {
403   assert(PI.Pid && "invalid pid to wait on, process not started?");
404   assert(PI.ProcessHandle &&
405          "invalid process handle to wait on, process not started?");
406   DWORD milliSecondsToWait = 0;
407   if (WaitUntilChildTerminates)
408     milliSecondsToWait = INFINITE;
409   else if (SecondsToWait > 0)
410     milliSecondsToWait = SecondsToWait * 1000;
411
412   ProcessInfo WaitResult = PI;
413   DWORD WaitStatus = WaitForSingleObject(PI.ProcessHandle, milliSecondsToWait);
414   if (WaitStatus == WAIT_TIMEOUT) {
415     if (SecondsToWait) {
416       if (!TerminateProcess(PI.ProcessHandle, 1)) {
417         if (ErrMsg)
418           MakeErrMsg(ErrMsg, "Failed to terminate timed-out program.");
419
420         // -2 indicates a crash or timeout as opposed to failure to execute.
421         WaitResult.ReturnCode = -2;
422         CloseHandle(PI.ProcessHandle);
423         return WaitResult;
424       }
425       WaitForSingleObject(PI.ProcessHandle, INFINITE);
426       CloseHandle(PI.ProcessHandle);
427     } else {
428       // Non-blocking wait.
429       return ProcessInfo();
430     }
431   }
432
433   // Get its exit status.
434   DWORD status;
435   BOOL rc = GetExitCodeProcess(PI.ProcessHandle, &status);
436   DWORD err = GetLastError();
437   CloseHandle(PI.ProcessHandle);
438
439   if (!rc) {
440     SetLastError(err);
441     if (ErrMsg)
442       MakeErrMsg(ErrMsg, "Failed getting status for program.");
443
444     // -2 indicates a crash or timeout as opposed to failure to execute.
445     WaitResult.ReturnCode = -2;
446     return WaitResult;
447   }
448
449   if (!status)
450     return WaitResult;
451
452   // Pass 10(Warning) and 11(Error) to the callee as negative value.
453   if ((status & 0xBFFF0000U) == 0x80000000U)
454     WaitResult.ReturnCode = static_cast<int>(status);
455   else if (status & 0xFF)
456     WaitResult.ReturnCode = status & 0x7FFFFFFF;
457   else
458     WaitResult.ReturnCode = 1;
459
460   return WaitResult;
461 }
462
463 std::error_code sys::ChangeStdinToBinary() {
464   int result = _setmode(_fileno(stdin), _O_BINARY);
465   if (result == -1)
466     return std::error_code(errno, std::generic_category());
467   return std::error_code();
468 }
469
470 std::error_code sys::ChangeStdoutToBinary() {
471   int result = _setmode(_fileno(stdout), _O_BINARY);
472   if (result == -1)
473     return std::error_code(errno, std::generic_category());
474   return std::error_code();
475 }
476
477 std::error_code
478 llvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents,
479                                  WindowsEncodingMethod Encoding) {
480   std::error_code EC;
481   llvm::raw_fd_ostream OS(FileName, EC, llvm::sys::fs::OpenFlags::F_Text);
482   if (EC)
483     return EC;
484
485   if (Encoding == WEM_UTF8) {
486     OS << Contents;
487   } else if (Encoding == WEM_CurrentCodePage) {
488     SmallVector<wchar_t, 1> ArgsUTF16;
489     SmallVector<char, 1> ArgsCurCP;
490
491     if ((EC = windows::UTF8ToUTF16(Contents, ArgsUTF16)))
492       return EC;
493
494     if ((EC = windows::UTF16ToCurCP(
495              ArgsUTF16.data(), ArgsUTF16.size(), ArgsCurCP)))
496       return EC;
497
498     OS.write(ArgsCurCP.data(), ArgsCurCP.size());
499   } else if (Encoding == WEM_UTF16) {
500     SmallVector<wchar_t, 1> ArgsUTF16;
501
502     if ((EC = windows::UTF8ToUTF16(Contents, ArgsUTF16)))
503       return EC;
504
505     // Endianness guessing
506     char BOM[2];
507     uint16_t src = UNI_UTF16_BYTE_ORDER_MARK_NATIVE;
508     memcpy(BOM, &src, 2);
509     OS.write(BOM, 2);
510     OS.write((char *)ArgsUTF16.data(), ArgsUTF16.size() << 1);
511   } else {
512     llvm_unreachable("Unknown encoding");
513   }
514
515   if (OS.has_error())
516     return std::make_error_code(std::errc::io_error);
517
518   return EC;
519 }
520
521 bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef<const char*> Args) {
522   // The documented max length of the command line passed to CreateProcess.
523   static const size_t MaxCommandStringLength = 32768;
524   size_t ArgLength = 0;
525   for (ArrayRef<const char*>::iterator I = Args.begin(), E = Args.end();
526        I != E; ++I) {
527     // Account for the trailing space for every arg but the last one and the
528     // trailing NULL of the last argument.
529     ArgLength += ArgLenWithQuotes(*I) + 1;
530     if (ArgLength > MaxCommandStringLength) {
531       return false;
532     }
533   }
534   return true;
535 }
536 }