1*9880d681SAndroid Build Coastguard Worker//===- Win32/Process.cpp - Win32 Process 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 Process class. 11*9880d681SAndroid Build Coastguard Worker// 12*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/Allocator.h" 15*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/ErrorHandling.h" 16*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/WindowsError.h" 17*9880d681SAndroid Build Coastguard Worker#include <malloc.h> 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Worker// The Windows.h header must be after LLVM and standard headers. 20*9880d681SAndroid Build Coastguard Worker#include "WindowsSupport.h" 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Worker#include <direct.h> 23*9880d681SAndroid Build Coastguard Worker#include <io.h> 24*9880d681SAndroid Build Coastguard Worker#include <psapi.h> 25*9880d681SAndroid Build Coastguard Worker#include <shellapi.h> 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Worker#ifdef __MINGW32__ 28*9880d681SAndroid Build Coastguard Worker #if (HAVE_LIBPSAPI != 1) 29*9880d681SAndroid Build Coastguard Worker #error "libpsapi.a should be present" 30*9880d681SAndroid Build Coastguard Worker #endif 31*9880d681SAndroid Build Coastguard Worker #if (HAVE_LIBSHELL32 != 1) 32*9880d681SAndroid Build Coastguard Worker #error "libshell32.a should be present" 33*9880d681SAndroid Build Coastguard Worker #endif 34*9880d681SAndroid Build Coastguard Worker#else 35*9880d681SAndroid Build Coastguard Worker #pragma comment(lib, "psapi.lib") 36*9880d681SAndroid Build Coastguard Worker #pragma comment(lib, "shell32.lib") 37*9880d681SAndroid Build Coastguard Worker#endif 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 40*9880d681SAndroid Build Coastguard Worker//=== WARNING: Implementation here must contain only Win32 specific code 41*9880d681SAndroid Build Coastguard Worker//=== and must not be UNIX code 42*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Worker#ifdef __MINGW32__ 45*9880d681SAndroid Build Coastguard Worker// This ban should be lifted when MinGW 1.0+ has defined this value. 46*9880d681SAndroid Build Coastguard Worker# define _HEAPOK (-2) 47*9880d681SAndroid Build Coastguard Worker#endif 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Workerusing namespace llvm; 50*9880d681SAndroid Build Coastguard Workerusing namespace sys; 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Workerstatic TimeValue getTimeValueFromFILETIME(FILETIME Time) { 53*9880d681SAndroid Build Coastguard Worker ULARGE_INTEGER TimeInteger; 54*9880d681SAndroid Build Coastguard Worker TimeInteger.LowPart = Time.dwLowDateTime; 55*9880d681SAndroid Build Coastguard Worker TimeInteger.HighPart = Time.dwHighDateTime; 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond) 58*9880d681SAndroid Build Coastguard Worker return TimeValue( 59*9880d681SAndroid Build Coastguard Worker static_cast<TimeValue::SecondsType>(TimeInteger.QuadPart / 10000000), 60*9880d681SAndroid Build Coastguard Worker static_cast<TimeValue::NanoSecondsType>( 61*9880d681SAndroid Build Coastguard Worker (TimeInteger.QuadPart % 10000000) * 100)); 62*9880d681SAndroid Build Coastguard Worker} 63*9880d681SAndroid Build Coastguard Worker 64*9880d681SAndroid Build Coastguard Worker// This function retrieves the page size using GetNativeSystemInfo() and is 65*9880d681SAndroid Build Coastguard Worker// present solely so it can be called once to initialize the self_process member 66*9880d681SAndroid Build Coastguard Worker// below. 67*9880d681SAndroid Build Coastguard Workerstatic unsigned computePageSize() { 68*9880d681SAndroid Build Coastguard Worker // GetNativeSystemInfo() provides the physical page size which may differ 69*9880d681SAndroid Build Coastguard Worker // from GetSystemInfo() in 32-bit applications running under WOW64. 70*9880d681SAndroid Build Coastguard Worker SYSTEM_INFO info; 71*9880d681SAndroid Build Coastguard Worker GetNativeSystemInfo(&info); 72*9880d681SAndroid Build Coastguard Worker // FIXME: FileOffset in MapViewOfFile() should be aligned to not dwPageSize, 73*9880d681SAndroid Build Coastguard Worker // but dwAllocationGranularity. 74*9880d681SAndroid Build Coastguard Worker return static_cast<unsigned>(info.dwPageSize); 75*9880d681SAndroid Build Coastguard Worker} 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Workerunsigned Process::getPageSize() { 78*9880d681SAndroid Build Coastguard Worker static unsigned Ret = computePageSize(); 79*9880d681SAndroid Build Coastguard Worker return Ret; 80*9880d681SAndroid Build Coastguard Worker} 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Workersize_t 83*9880d681SAndroid Build Coastguard WorkerProcess::GetMallocUsage() 84*9880d681SAndroid Build Coastguard Worker{ 85*9880d681SAndroid Build Coastguard Worker _HEAPINFO hinfo; 86*9880d681SAndroid Build Coastguard Worker hinfo._pentry = NULL; 87*9880d681SAndroid Build Coastguard Worker 88*9880d681SAndroid Build Coastguard Worker size_t size = 0; 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker while (_heapwalk(&hinfo) == _HEAPOK) 91*9880d681SAndroid Build Coastguard Worker size += hinfo._size; 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Worker return size; 94*9880d681SAndroid Build Coastguard Worker} 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Workervoid Process::GetTimeUsage(TimeValue &elapsed, TimeValue &user_time, 97*9880d681SAndroid Build Coastguard Worker TimeValue &sys_time) { 98*9880d681SAndroid Build Coastguard Worker elapsed = TimeValue::now(); 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Worker FILETIME ProcCreate, ProcExit, KernelTime, UserTime; 101*9880d681SAndroid Build Coastguard Worker if (GetProcessTimes(GetCurrentProcess(), &ProcCreate, &ProcExit, &KernelTime, 102*9880d681SAndroid Build Coastguard Worker &UserTime) == 0) 103*9880d681SAndroid Build Coastguard Worker return; 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Worker user_time = getTimeValueFromFILETIME(UserTime); 106*9880d681SAndroid Build Coastguard Worker sys_time = getTimeValueFromFILETIME(KernelTime); 107*9880d681SAndroid Build Coastguard Worker} 108*9880d681SAndroid Build Coastguard Worker 109*9880d681SAndroid Build Coastguard Worker// Some LLVM programs such as bugpoint produce core files as a normal part of 110*9880d681SAndroid Build Coastguard Worker// their operation. To prevent the disk from filling up, this configuration 111*9880d681SAndroid Build Coastguard Worker// item does what's necessary to prevent their generation. 112*9880d681SAndroid Build Coastguard Workervoid Process::PreventCoreFiles() { 113*9880d681SAndroid Build Coastguard Worker // Windows does have the concept of core files, called minidumps. However, 114*9880d681SAndroid Build Coastguard Worker // disabling minidumps for a particular application extends past the lifetime 115*9880d681SAndroid Build Coastguard Worker // of that application, which is the incorrect behavior for this API. 116*9880d681SAndroid Build Coastguard Worker // Additionally, the APIs require elevated privileges to disable and re- 117*9880d681SAndroid Build Coastguard Worker // enable minidumps, which makes this untenable. For more information, see 118*9880d681SAndroid Build Coastguard Worker // WerAddExcludedApplication and WerRemoveExcludedApplication (Vista and 119*9880d681SAndroid Build Coastguard Worker // later). 120*9880d681SAndroid Build Coastguard Worker // 121*9880d681SAndroid Build Coastguard Worker // Windows also has modal pop-up message boxes. As this method is used by 122*9880d681SAndroid Build Coastguard Worker // bugpoint, preventing these pop-ups is additionally important. 123*9880d681SAndroid Build Coastguard Worker SetErrorMode(SEM_FAILCRITICALERRORS | 124*9880d681SAndroid Build Coastguard Worker SEM_NOGPFAULTERRORBOX | 125*9880d681SAndroid Build Coastguard Worker SEM_NOOPENFILEERRORBOX); 126*9880d681SAndroid Build Coastguard Worker 127*9880d681SAndroid Build Coastguard Worker coreFilesPrevented = true; 128*9880d681SAndroid Build Coastguard Worker} 129*9880d681SAndroid Build Coastguard Worker 130*9880d681SAndroid Build Coastguard Worker/// Returns the environment variable \arg Name's value as a string encoded in 131*9880d681SAndroid Build Coastguard Worker/// UTF-8. \arg Name is assumed to be in UTF-8 encoding. 132*9880d681SAndroid Build Coastguard WorkerOptional<std::string> Process::GetEnv(StringRef Name) { 133*9880d681SAndroid Build Coastguard Worker // Convert the argument to UTF-16 to pass it to _wgetenv(). 134*9880d681SAndroid Build Coastguard Worker SmallVector<wchar_t, 128> NameUTF16; 135*9880d681SAndroid Build Coastguard Worker if (windows::UTF8ToUTF16(Name, NameUTF16)) 136*9880d681SAndroid Build Coastguard Worker return None; 137*9880d681SAndroid Build Coastguard Worker 138*9880d681SAndroid Build Coastguard Worker // Environment variable can be encoded in non-UTF8 encoding, and there's no 139*9880d681SAndroid Build Coastguard Worker // way to know what the encoding is. The only reliable way to look up 140*9880d681SAndroid Build Coastguard Worker // multibyte environment variable is to use GetEnvironmentVariableW(). 141*9880d681SAndroid Build Coastguard Worker SmallVector<wchar_t, MAX_PATH> Buf; 142*9880d681SAndroid Build Coastguard Worker size_t Size = MAX_PATH; 143*9880d681SAndroid Build Coastguard Worker do { 144*9880d681SAndroid Build Coastguard Worker Buf.reserve(Size); 145*9880d681SAndroid Build Coastguard Worker Size = 146*9880d681SAndroid Build Coastguard Worker GetEnvironmentVariableW(NameUTF16.data(), Buf.data(), Buf.capacity()); 147*9880d681SAndroid Build Coastguard Worker if (Size == 0) 148*9880d681SAndroid Build Coastguard Worker return None; 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Worker // Try again with larger buffer. 151*9880d681SAndroid Build Coastguard Worker } while (Size > Buf.capacity()); 152*9880d681SAndroid Build Coastguard Worker Buf.set_size(Size); 153*9880d681SAndroid Build Coastguard Worker 154*9880d681SAndroid Build Coastguard Worker // Convert the result from UTF-16 to UTF-8. 155*9880d681SAndroid Build Coastguard Worker SmallVector<char, MAX_PATH> Res; 156*9880d681SAndroid Build Coastguard Worker if (windows::UTF16ToUTF8(Buf.data(), Size, Res)) 157*9880d681SAndroid Build Coastguard Worker return None; 158*9880d681SAndroid Build Coastguard Worker return std::string(Res.data()); 159*9880d681SAndroid Build Coastguard Worker} 160*9880d681SAndroid Build Coastguard Worker 161*9880d681SAndroid Build Coastguard Workerstatic void AllocateAndPush(const SmallVectorImpl<char> &S, 162*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<const char *> &Vector, 163*9880d681SAndroid Build Coastguard Worker SpecificBumpPtrAllocator<char> &Allocator) { 164*9880d681SAndroid Build Coastguard Worker char *Buffer = Allocator.Allocate(S.size() + 1); 165*9880d681SAndroid Build Coastguard Worker ::memcpy(Buffer, S.data(), S.size()); 166*9880d681SAndroid Build Coastguard Worker Buffer[S.size()] = '\0'; 167*9880d681SAndroid Build Coastguard Worker Vector.push_back(Buffer); 168*9880d681SAndroid Build Coastguard Worker} 169*9880d681SAndroid Build Coastguard Worker 170*9880d681SAndroid Build Coastguard Worker/// Convert Arg from UTF-16 to UTF-8 and push it onto Args. 171*9880d681SAndroid Build Coastguard Workerstatic std::error_code 172*9880d681SAndroid Build Coastguard WorkerConvertAndPushArg(const wchar_t *Arg, SmallVectorImpl<const char *> &Args, 173*9880d681SAndroid Build Coastguard Worker SpecificBumpPtrAllocator<char> &Allocator) { 174*9880d681SAndroid Build Coastguard Worker SmallVector<char, MAX_PATH> ArgString; 175*9880d681SAndroid Build Coastguard Worker if (std::error_code ec = windows::UTF16ToUTF8(Arg, wcslen(Arg), ArgString)) 176*9880d681SAndroid Build Coastguard Worker return ec; 177*9880d681SAndroid Build Coastguard Worker AllocateAndPush(ArgString, Args, Allocator); 178*9880d681SAndroid Build Coastguard Worker return std::error_code(); 179*9880d681SAndroid Build Coastguard Worker} 180*9880d681SAndroid Build Coastguard Worker 181*9880d681SAndroid Build Coastguard Worker/// \brief Perform wildcard expansion of Arg, or just push it into Args if it 182*9880d681SAndroid Build Coastguard Worker/// doesn't have wildcards or doesn't match any files. 183*9880d681SAndroid Build Coastguard Workerstatic std::error_code 184*9880d681SAndroid Build Coastguard WorkerWildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args, 185*9880d681SAndroid Build Coastguard Worker SpecificBumpPtrAllocator<char> &Allocator) { 186*9880d681SAndroid Build Coastguard Worker if (!wcspbrk(Arg, L"*?")) { 187*9880d681SAndroid Build Coastguard Worker // Arg does not contain any wildcard characters. This is the common case. 188*9880d681SAndroid Build Coastguard Worker return ConvertAndPushArg(Arg, Args, Allocator); 189*9880d681SAndroid Build Coastguard Worker } 190*9880d681SAndroid Build Coastguard Worker 191*9880d681SAndroid Build Coastguard Worker if (wcscmp(Arg, L"/?") == 0 || wcscmp(Arg, L"-?") == 0) { 192*9880d681SAndroid Build Coastguard Worker // Don't wildcard expand /?. Always treat it as an option. 193*9880d681SAndroid Build Coastguard Worker return ConvertAndPushArg(Arg, Args, Allocator); 194*9880d681SAndroid Build Coastguard Worker } 195*9880d681SAndroid Build Coastguard Worker 196*9880d681SAndroid Build Coastguard Worker // Extract any directory part of the argument. 197*9880d681SAndroid Build Coastguard Worker SmallVector<char, MAX_PATH> Dir; 198*9880d681SAndroid Build Coastguard Worker if (std::error_code ec = windows::UTF16ToUTF8(Arg, wcslen(Arg), Dir)) 199*9880d681SAndroid Build Coastguard Worker return ec; 200*9880d681SAndroid Build Coastguard Worker sys::path::remove_filename(Dir); 201*9880d681SAndroid Build Coastguard Worker const int DirSize = Dir.size(); 202*9880d681SAndroid Build Coastguard Worker 203*9880d681SAndroid Build Coastguard Worker // Search for matching files. 204*9880d681SAndroid Build Coastguard Worker // FIXME: This assumes the wildcard is only in the file name and not in the 205*9880d681SAndroid Build Coastguard Worker // directory portion of the file path. For example, it doesn't handle 206*9880d681SAndroid Build Coastguard Worker // "*\foo.c" nor "s?c\bar.cpp". 207*9880d681SAndroid Build Coastguard Worker WIN32_FIND_DATAW FileData; 208*9880d681SAndroid Build Coastguard Worker HANDLE FindHandle = FindFirstFileW(Arg, &FileData); 209*9880d681SAndroid Build Coastguard Worker if (FindHandle == INVALID_HANDLE_VALUE) { 210*9880d681SAndroid Build Coastguard Worker return ConvertAndPushArg(Arg, Args, Allocator); 211*9880d681SAndroid Build Coastguard Worker } 212*9880d681SAndroid Build Coastguard Worker 213*9880d681SAndroid Build Coastguard Worker std::error_code ec; 214*9880d681SAndroid Build Coastguard Worker do { 215*9880d681SAndroid Build Coastguard Worker SmallVector<char, MAX_PATH> FileName; 216*9880d681SAndroid Build Coastguard Worker ec = windows::UTF16ToUTF8(FileData.cFileName, wcslen(FileData.cFileName), 217*9880d681SAndroid Build Coastguard Worker FileName); 218*9880d681SAndroid Build Coastguard Worker if (ec) 219*9880d681SAndroid Build Coastguard Worker break; 220*9880d681SAndroid Build Coastguard Worker 221*9880d681SAndroid Build Coastguard Worker // Append FileName to Dir, and remove it afterwards. 222*9880d681SAndroid Build Coastguard Worker llvm::sys::path::append(Dir, StringRef(FileName.data(), FileName.size())); 223*9880d681SAndroid Build Coastguard Worker AllocateAndPush(Dir, Args, Allocator); 224*9880d681SAndroid Build Coastguard Worker Dir.resize(DirSize); 225*9880d681SAndroid Build Coastguard Worker } while (FindNextFileW(FindHandle, &FileData)); 226*9880d681SAndroid Build Coastguard Worker 227*9880d681SAndroid Build Coastguard Worker FindClose(FindHandle); 228*9880d681SAndroid Build Coastguard Worker return ec; 229*9880d681SAndroid Build Coastguard Worker} 230*9880d681SAndroid Build Coastguard Worker 231*9880d681SAndroid Build Coastguard Workerstatic std::error_code 232*9880d681SAndroid Build Coastguard WorkerExpandShortFileName(const wchar_t *Arg, SmallVectorImpl<const char *> &Args, 233*9880d681SAndroid Build Coastguard Worker SpecificBumpPtrAllocator<char> &Allocator) { 234*9880d681SAndroid Build Coastguard Worker SmallVector<wchar_t, MAX_PATH> LongPath; 235*9880d681SAndroid Build Coastguard Worker DWORD Length = GetLongPathNameW(Arg, LongPath.data(), LongPath.capacity()); 236*9880d681SAndroid Build Coastguard Worker if (Length == 0) 237*9880d681SAndroid Build Coastguard Worker return mapWindowsError(GetLastError()); 238*9880d681SAndroid Build Coastguard Worker if (Length > LongPath.capacity()) { 239*9880d681SAndroid Build Coastguard Worker // We're not going to try to deal with paths longer than MAX_PATH, so we'll 240*9880d681SAndroid Build Coastguard Worker // treat this as an error. GetLastError() returns ERROR_SUCCESS, which 241*9880d681SAndroid Build Coastguard Worker // isn't useful, so we'll hardcode an appropriate error value. 242*9880d681SAndroid Build Coastguard Worker return mapWindowsError(ERROR_INSUFFICIENT_BUFFER); 243*9880d681SAndroid Build Coastguard Worker } 244*9880d681SAndroid Build Coastguard Worker LongPath.set_size(Length); 245*9880d681SAndroid Build Coastguard Worker return ConvertAndPushArg(LongPath.data(), Args, Allocator); 246*9880d681SAndroid Build Coastguard Worker} 247*9880d681SAndroid Build Coastguard Worker 248*9880d681SAndroid Build Coastguard Workerstd::error_code 249*9880d681SAndroid Build Coastguard WorkerProcess::GetArgumentVector(SmallVectorImpl<const char *> &Args, 250*9880d681SAndroid Build Coastguard Worker ArrayRef<const char *>, 251*9880d681SAndroid Build Coastguard Worker SpecificBumpPtrAllocator<char> &ArgAllocator) { 252*9880d681SAndroid Build Coastguard Worker int ArgCount; 253*9880d681SAndroid Build Coastguard Worker wchar_t **UnicodeCommandLine = 254*9880d681SAndroid Build Coastguard Worker CommandLineToArgvW(GetCommandLineW(), &ArgCount); 255*9880d681SAndroid Build Coastguard Worker if (!UnicodeCommandLine) 256*9880d681SAndroid Build Coastguard Worker return mapWindowsError(::GetLastError()); 257*9880d681SAndroid Build Coastguard Worker 258*9880d681SAndroid Build Coastguard Worker Args.reserve(ArgCount); 259*9880d681SAndroid Build Coastguard Worker std::error_code ec; 260*9880d681SAndroid Build Coastguard Worker 261*9880d681SAndroid Build Coastguard Worker // The first argument may contain just the name of the executable (e.g., 262*9880d681SAndroid Build Coastguard Worker // "clang") rather than the full path, so swap it with the full path. 263*9880d681SAndroid Build Coastguard Worker wchar_t ModuleName[MAX_PATH]; 264*9880d681SAndroid Build Coastguard Worker int Length = ::GetModuleFileNameW(NULL, ModuleName, MAX_PATH); 265*9880d681SAndroid Build Coastguard Worker if (0 < Length && Length < MAX_PATH) 266*9880d681SAndroid Build Coastguard Worker UnicodeCommandLine[0] = ModuleName; 267*9880d681SAndroid Build Coastguard Worker 268*9880d681SAndroid Build Coastguard Worker // If the first argument is a shortened (8.3) name (which is possible even 269*9880d681SAndroid Build Coastguard Worker // if we got the module name), the driver will have trouble distinguishing it 270*9880d681SAndroid Build Coastguard Worker // (e.g., clang.exe v. clang++.exe), so expand it now. 271*9880d681SAndroid Build Coastguard Worker ec = ExpandShortFileName(UnicodeCommandLine[0], Args, ArgAllocator); 272*9880d681SAndroid Build Coastguard Worker 273*9880d681SAndroid Build Coastguard Worker for (int i = 1; i < ArgCount && !ec; ++i) { 274*9880d681SAndroid Build Coastguard Worker ec = WildcardExpand(UnicodeCommandLine[i], Args, ArgAllocator); 275*9880d681SAndroid Build Coastguard Worker if (ec) 276*9880d681SAndroid Build Coastguard Worker break; 277*9880d681SAndroid Build Coastguard Worker } 278*9880d681SAndroid Build Coastguard Worker 279*9880d681SAndroid Build Coastguard Worker LocalFree(UnicodeCommandLine); 280*9880d681SAndroid Build Coastguard Worker return ec; 281*9880d681SAndroid Build Coastguard Worker} 282*9880d681SAndroid Build Coastguard Worker 283*9880d681SAndroid Build Coastguard Workerstd::error_code Process::FixupStandardFileDescriptors() { 284*9880d681SAndroid Build Coastguard Worker return std::error_code(); 285*9880d681SAndroid Build Coastguard Worker} 286*9880d681SAndroid Build Coastguard Worker 287*9880d681SAndroid Build Coastguard Workerstd::error_code Process::SafelyCloseFileDescriptor(int FD) { 288*9880d681SAndroid Build Coastguard Worker if (::close(FD) < 0) 289*9880d681SAndroid Build Coastguard Worker return std::error_code(errno, std::generic_category()); 290*9880d681SAndroid Build Coastguard Worker return std::error_code(); 291*9880d681SAndroid Build Coastguard Worker} 292*9880d681SAndroid Build Coastguard Worker 293*9880d681SAndroid Build Coastguard Workerbool Process::StandardInIsUserInput() { 294*9880d681SAndroid Build Coastguard Worker return FileDescriptorIsDisplayed(0); 295*9880d681SAndroid Build Coastguard Worker} 296*9880d681SAndroid Build Coastguard Worker 297*9880d681SAndroid Build Coastguard Workerbool Process::StandardOutIsDisplayed() { 298*9880d681SAndroid Build Coastguard Worker return FileDescriptorIsDisplayed(1); 299*9880d681SAndroid Build Coastguard Worker} 300*9880d681SAndroid Build Coastguard Worker 301*9880d681SAndroid Build Coastguard Workerbool Process::StandardErrIsDisplayed() { 302*9880d681SAndroid Build Coastguard Worker return FileDescriptorIsDisplayed(2); 303*9880d681SAndroid Build Coastguard Worker} 304*9880d681SAndroid Build Coastguard Worker 305*9880d681SAndroid Build Coastguard Workerbool Process::FileDescriptorIsDisplayed(int fd) { 306*9880d681SAndroid Build Coastguard Worker DWORD Mode; // Unused 307*9880d681SAndroid Build Coastguard Worker return (GetConsoleMode((HANDLE)_get_osfhandle(fd), &Mode) != 0); 308*9880d681SAndroid Build Coastguard Worker} 309*9880d681SAndroid Build Coastguard Worker 310*9880d681SAndroid Build Coastguard Workerunsigned Process::StandardOutColumns() { 311*9880d681SAndroid Build Coastguard Worker unsigned Columns = 0; 312*9880d681SAndroid Build Coastguard Worker CONSOLE_SCREEN_BUFFER_INFO csbi; 313*9880d681SAndroid Build Coastguard Worker if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) 314*9880d681SAndroid Build Coastguard Worker Columns = csbi.dwSize.X; 315*9880d681SAndroid Build Coastguard Worker return Columns; 316*9880d681SAndroid Build Coastguard Worker} 317*9880d681SAndroid Build Coastguard Worker 318*9880d681SAndroid Build Coastguard Workerunsigned Process::StandardErrColumns() { 319*9880d681SAndroid Build Coastguard Worker unsigned Columns = 0; 320*9880d681SAndroid Build Coastguard Worker CONSOLE_SCREEN_BUFFER_INFO csbi; 321*9880d681SAndroid Build Coastguard Worker if (GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), &csbi)) 322*9880d681SAndroid Build Coastguard Worker Columns = csbi.dwSize.X; 323*9880d681SAndroid Build Coastguard Worker return Columns; 324*9880d681SAndroid Build Coastguard Worker} 325*9880d681SAndroid Build Coastguard Worker 326*9880d681SAndroid Build Coastguard Worker// The terminal always has colors. 327*9880d681SAndroid Build Coastguard Workerbool Process::FileDescriptorHasColors(int fd) { 328*9880d681SAndroid Build Coastguard Worker return FileDescriptorIsDisplayed(fd); 329*9880d681SAndroid Build Coastguard Worker} 330*9880d681SAndroid Build Coastguard Worker 331*9880d681SAndroid Build Coastguard Workerbool Process::StandardOutHasColors() { 332*9880d681SAndroid Build Coastguard Worker return FileDescriptorHasColors(1); 333*9880d681SAndroid Build Coastguard Worker} 334*9880d681SAndroid Build Coastguard Worker 335*9880d681SAndroid Build Coastguard Workerbool Process::StandardErrHasColors() { 336*9880d681SAndroid Build Coastguard Worker return FileDescriptorHasColors(2); 337*9880d681SAndroid Build Coastguard Worker} 338*9880d681SAndroid Build Coastguard Worker 339*9880d681SAndroid Build Coastguard Workerstatic bool UseANSI = false; 340*9880d681SAndroid Build Coastguard Workervoid Process::UseANSIEscapeCodes(bool enable) { 341*9880d681SAndroid Build Coastguard Worker UseANSI = enable; 342*9880d681SAndroid Build Coastguard Worker} 343*9880d681SAndroid Build Coastguard Worker 344*9880d681SAndroid Build Coastguard Workernamespace { 345*9880d681SAndroid Build Coastguard Workerclass DefaultColors 346*9880d681SAndroid Build Coastguard Worker{ 347*9880d681SAndroid Build Coastguard Worker private: 348*9880d681SAndroid Build Coastguard Worker WORD defaultColor; 349*9880d681SAndroid Build Coastguard Worker public: 350*9880d681SAndroid Build Coastguard Worker DefaultColors() 351*9880d681SAndroid Build Coastguard Worker :defaultColor(GetCurrentColor()) {} 352*9880d681SAndroid Build Coastguard Worker static unsigned GetCurrentColor() { 353*9880d681SAndroid Build Coastguard Worker CONSOLE_SCREEN_BUFFER_INFO csbi; 354*9880d681SAndroid Build Coastguard Worker if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) 355*9880d681SAndroid Build Coastguard Worker return csbi.wAttributes; 356*9880d681SAndroid Build Coastguard Worker return 0; 357*9880d681SAndroid Build Coastguard Worker } 358*9880d681SAndroid Build Coastguard Worker WORD operator()() const { return defaultColor; } 359*9880d681SAndroid Build Coastguard Worker}; 360*9880d681SAndroid Build Coastguard Worker 361*9880d681SAndroid Build Coastguard WorkerDefaultColors defaultColors; 362*9880d681SAndroid Build Coastguard Worker 363*9880d681SAndroid Build Coastguard WorkerWORD fg_color(WORD color) { 364*9880d681SAndroid Build Coastguard Worker return color & (FOREGROUND_BLUE | FOREGROUND_GREEN | 365*9880d681SAndroid Build Coastguard Worker FOREGROUND_INTENSITY | FOREGROUND_RED); 366*9880d681SAndroid Build Coastguard Worker} 367*9880d681SAndroid Build Coastguard Worker 368*9880d681SAndroid Build Coastguard WorkerWORD bg_color(WORD color) { 369*9880d681SAndroid Build Coastguard Worker return color & (BACKGROUND_BLUE | BACKGROUND_GREEN | 370*9880d681SAndroid Build Coastguard Worker BACKGROUND_INTENSITY | BACKGROUND_RED); 371*9880d681SAndroid Build Coastguard Worker} 372*9880d681SAndroid Build Coastguard Worker} 373*9880d681SAndroid Build Coastguard Worker 374*9880d681SAndroid Build Coastguard Workerbool Process::ColorNeedsFlush() { 375*9880d681SAndroid Build Coastguard Worker return !UseANSI; 376*9880d681SAndroid Build Coastguard Worker} 377*9880d681SAndroid Build Coastguard Worker 378*9880d681SAndroid Build Coastguard Workerconst char *Process::OutputBold(bool bg) { 379*9880d681SAndroid Build Coastguard Worker if (UseANSI) return "\033[1m"; 380*9880d681SAndroid Build Coastguard Worker 381*9880d681SAndroid Build Coastguard Worker WORD colors = DefaultColors::GetCurrentColor(); 382*9880d681SAndroid Build Coastguard Worker if (bg) 383*9880d681SAndroid Build Coastguard Worker colors |= BACKGROUND_INTENSITY; 384*9880d681SAndroid Build Coastguard Worker else 385*9880d681SAndroid Build Coastguard Worker colors |= FOREGROUND_INTENSITY; 386*9880d681SAndroid Build Coastguard Worker SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors); 387*9880d681SAndroid Build Coastguard Worker return 0; 388*9880d681SAndroid Build Coastguard Worker} 389*9880d681SAndroid Build Coastguard Worker 390*9880d681SAndroid Build Coastguard Workerconst char *Process::OutputColor(char code, bool bold, bool bg) { 391*9880d681SAndroid Build Coastguard Worker if (UseANSI) return colorcodes[bg?1:0][bold?1:0][code&7]; 392*9880d681SAndroid Build Coastguard Worker 393*9880d681SAndroid Build Coastguard Worker WORD current = DefaultColors::GetCurrentColor(); 394*9880d681SAndroid Build Coastguard Worker WORD colors; 395*9880d681SAndroid Build Coastguard Worker if (bg) { 396*9880d681SAndroid Build Coastguard Worker colors = ((code&1) ? BACKGROUND_RED : 0) | 397*9880d681SAndroid Build Coastguard Worker ((code&2) ? BACKGROUND_GREEN : 0 ) | 398*9880d681SAndroid Build Coastguard Worker ((code&4) ? BACKGROUND_BLUE : 0); 399*9880d681SAndroid Build Coastguard Worker if (bold) 400*9880d681SAndroid Build Coastguard Worker colors |= BACKGROUND_INTENSITY; 401*9880d681SAndroid Build Coastguard Worker colors |= fg_color(current); 402*9880d681SAndroid Build Coastguard Worker } else { 403*9880d681SAndroid Build Coastguard Worker colors = ((code&1) ? FOREGROUND_RED : 0) | 404*9880d681SAndroid Build Coastguard Worker ((code&2) ? FOREGROUND_GREEN : 0 ) | 405*9880d681SAndroid Build Coastguard Worker ((code&4) ? FOREGROUND_BLUE : 0); 406*9880d681SAndroid Build Coastguard Worker if (bold) 407*9880d681SAndroid Build Coastguard Worker colors |= FOREGROUND_INTENSITY; 408*9880d681SAndroid Build Coastguard Worker colors |= bg_color(current); 409*9880d681SAndroid Build Coastguard Worker } 410*9880d681SAndroid Build Coastguard Worker SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors); 411*9880d681SAndroid Build Coastguard Worker return 0; 412*9880d681SAndroid Build Coastguard Worker} 413*9880d681SAndroid Build Coastguard Worker 414*9880d681SAndroid Build Coastguard Workerstatic WORD GetConsoleTextAttribute(HANDLE hConsoleOutput) { 415*9880d681SAndroid Build Coastguard Worker CONSOLE_SCREEN_BUFFER_INFO info; 416*9880d681SAndroid Build Coastguard Worker GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info); 417*9880d681SAndroid Build Coastguard Worker return info.wAttributes; 418*9880d681SAndroid Build Coastguard Worker} 419*9880d681SAndroid Build Coastguard Worker 420*9880d681SAndroid Build Coastguard Workerconst char *Process::OutputReverse() { 421*9880d681SAndroid Build Coastguard Worker if (UseANSI) return "\033[7m"; 422*9880d681SAndroid Build Coastguard Worker 423*9880d681SAndroid Build Coastguard Worker const WORD attributes 424*9880d681SAndroid Build Coastguard Worker = GetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE)); 425*9880d681SAndroid Build Coastguard Worker 426*9880d681SAndroid Build Coastguard Worker const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN | 427*9880d681SAndroid Build Coastguard Worker FOREGROUND_RED | FOREGROUND_INTENSITY; 428*9880d681SAndroid Build Coastguard Worker const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN | 429*9880d681SAndroid Build Coastguard Worker BACKGROUND_RED | BACKGROUND_INTENSITY; 430*9880d681SAndroid Build Coastguard Worker const WORD color_mask = foreground_mask | background_mask; 431*9880d681SAndroid Build Coastguard Worker 432*9880d681SAndroid Build Coastguard Worker WORD new_attributes = 433*9880d681SAndroid Build Coastguard Worker ((attributes & FOREGROUND_BLUE )?BACKGROUND_BLUE :0) | 434*9880d681SAndroid Build Coastguard Worker ((attributes & FOREGROUND_GREEN )?BACKGROUND_GREEN :0) | 435*9880d681SAndroid Build Coastguard Worker ((attributes & FOREGROUND_RED )?BACKGROUND_RED :0) | 436*9880d681SAndroid Build Coastguard Worker ((attributes & FOREGROUND_INTENSITY)?BACKGROUND_INTENSITY:0) | 437*9880d681SAndroid Build Coastguard Worker ((attributes & BACKGROUND_BLUE )?FOREGROUND_BLUE :0) | 438*9880d681SAndroid Build Coastguard Worker ((attributes & BACKGROUND_GREEN )?FOREGROUND_GREEN :0) | 439*9880d681SAndroid Build Coastguard Worker ((attributes & BACKGROUND_RED )?FOREGROUND_RED :0) | 440*9880d681SAndroid Build Coastguard Worker ((attributes & BACKGROUND_INTENSITY)?FOREGROUND_INTENSITY:0) | 441*9880d681SAndroid Build Coastguard Worker 0; 442*9880d681SAndroid Build Coastguard Worker new_attributes = (attributes & ~color_mask) | (new_attributes & color_mask); 443*9880d681SAndroid Build Coastguard Worker 444*9880d681SAndroid Build Coastguard Worker SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), new_attributes); 445*9880d681SAndroid Build Coastguard Worker return 0; 446*9880d681SAndroid Build Coastguard Worker} 447*9880d681SAndroid Build Coastguard Worker 448*9880d681SAndroid Build Coastguard Workerconst char *Process::ResetColor() { 449*9880d681SAndroid Build Coastguard Worker if (UseANSI) return "\033[0m"; 450*9880d681SAndroid Build Coastguard Worker SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), defaultColors()); 451*9880d681SAndroid Build Coastguard Worker return 0; 452*9880d681SAndroid Build Coastguard Worker} 453*9880d681SAndroid Build Coastguard Worker 454*9880d681SAndroid Build Coastguard Worker// Include GetLastError() in a fatal error message. 455*9880d681SAndroid Build Coastguard Workerstatic void ReportLastErrorFatal(const char *Msg) { 456*9880d681SAndroid Build Coastguard Worker std::string ErrMsg; 457*9880d681SAndroid Build Coastguard Worker MakeErrMsg(&ErrMsg, Msg); 458*9880d681SAndroid Build Coastguard Worker report_fatal_error(ErrMsg); 459*9880d681SAndroid Build Coastguard Worker} 460*9880d681SAndroid Build Coastguard Worker 461*9880d681SAndroid Build Coastguard Workerunsigned Process::GetRandomNumber() { 462*9880d681SAndroid Build Coastguard Worker HCRYPTPROV HCPC; 463*9880d681SAndroid Build Coastguard Worker if (!::CryptAcquireContextW(&HCPC, NULL, NULL, PROV_RSA_FULL, 464*9880d681SAndroid Build Coastguard Worker CRYPT_VERIFYCONTEXT)) 465*9880d681SAndroid Build Coastguard Worker ReportLastErrorFatal("Could not acquire a cryptographic context"); 466*9880d681SAndroid Build Coastguard Worker 467*9880d681SAndroid Build Coastguard Worker ScopedCryptContext CryptoProvider(HCPC); 468*9880d681SAndroid Build Coastguard Worker unsigned Ret; 469*9880d681SAndroid Build Coastguard Worker if (!::CryptGenRandom(CryptoProvider, sizeof(Ret), 470*9880d681SAndroid Build Coastguard Worker reinterpret_cast<BYTE *>(&Ret))) 471*9880d681SAndroid Build Coastguard Worker ReportLastErrorFatal("Could not generate a random number"); 472*9880d681SAndroid Build Coastguard Worker return Ret; 473*9880d681SAndroid Build Coastguard Worker} 474