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