summaryrefslogtreecommitdiff
path: root/lib/Support/Windows
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2013-10-06 20:44:34 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2013-10-06 20:44:34 +0000
commitb262556c45bb7b3add826bc3f050c99db6990c37 (patch)
tree78000a447829d54c2c4dfdae66314a83c8d2700a /lib/Support/Windows
parent5a1a1856a4dfa1335d937437fade5c0bbab06560 (diff)
downloadllvm-b262556c45bb7b3add826bc3f050c99db6990c37.tar.gz
llvm-b262556c45bb7b3add826bc3f050c99db6990c37.tar.bz2
llvm-b262556c45bb7b3add826bc3f050c99db6990c37.tar.xz
Revert "Windows: Add support for unicode command lines"
This is causing MinGW bots to fail. This reverts commit r192069. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192070 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/Windows')
-rw-r--r--lib/Support/Windows/DynamicLibrary.inc9
-rw-r--r--lib/Support/Windows/Path.inc29
-rw-r--r--lib/Support/Windows/Process.inc64
-rw-r--r--lib/Support/Windows/Program.inc126
-rw-r--r--lib/Support/Windows/Signals.inc2
-rw-r--r--lib/Support/Windows/Windows.h1
6 files changed, 83 insertions, 148 deletions
diff --git a/lib/Support/Windows/DynamicLibrary.inc b/lib/Support/Windows/DynamicLibrary.inc
index 5a7b21920a..2edaf74fa5 100644
--- a/lib/Support/Windows/DynamicLibrary.inc
+++ b/lib/Support/Windows/DynamicLibrary.inc
@@ -83,15 +83,8 @@ DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
// This is mostly to ensure that the return value still shows up as "valid".
return DynamicLibrary(&OpenedHandles);
}
-
- SmallVector<wchar_t, MAX_PATH> filenameUnicode;
- if (error_code ec = windows::UTF8ToUTF16(filename, filenameUnicode)) {
- SetLastError(ec.value());
- MakeErrMsg(errMsg, std::string(filename) + ": Can't convert to UTF-16: ");
- return DynamicLibrary();
- }
- HMODULE a_handle = LoadLibraryW(filenameUnicode.data());
+ HMODULE a_handle = LoadLibrary(filename);
if (a_handle == 0) {
MakeErrMsg(errMsg, std::string(filename) + ": Can't open : ");
diff --git a/lib/Support/Windows/Path.inc b/lib/Support/Windows/Path.inc
index 998ec422ec..94a501b39a 100644
--- a/lib/Support/Windows/Path.inc
+++ b/lib/Support/Windows/Path.inc
@@ -128,7 +128,7 @@ retry_random_path:
BYTE val = 0;
if (!::CryptGenRandom(CryptoProvider, 1, &val))
return windows_error(::GetLastError());
- random_path_utf16.push_back(L"0123456789abcdef"[val & 15]);
+ random_path_utf16.push_back("0123456789abcdef"[val & 15]);
}
else
random_path_utf16.push_back(*i);
@@ -241,23 +241,22 @@ TimeValue file_status::getLastModificationTime() const {
}
error_code current_path(SmallVectorImpl<char> &result) {
- SmallVector<wchar_t, MAX_PATH> cur_path;
- DWORD len = MAX_PATH;
+ SmallVector<wchar_t, 128> cur_path;
+ cur_path.reserve(128);
+retry_cur_dir:
+ DWORD len = ::GetCurrentDirectoryW(cur_path.capacity(), cur_path.data());
- do {
- cur_path.reserve(len);
- len = ::GetCurrentDirectoryW(cur_path.capacity(), cur_path.data());
-
- // A zero return value indicates a failure other than insufficient space.
- if (len == 0)
- return windows_error(::GetLastError());
+ // A zero return value indicates a failure other than insufficient space.
+ if (len == 0)
+ return windows_error(::GetLastError());
- // If there's insufficient space, the len returned is larger than the len
- // given.
- } while (len > cur_path.capacity());
+ // If there's insufficient space, the len returned is larger than the len
+ // given.
+ if (len > cur_path.capacity()) {
+ cur_path.reserve(len);
+ goto retry_cur_dir;
+ }
- // On success, GetCurrentDirectoryW returns the number of characters not
- // including the null-terminator.
cur_path.set_size(len);
return UTF16ToUTF8(cur_path.begin(), cur_path.size(), result);
}
diff --git a/lib/Support/Windows/Process.inc b/lib/Support/Windows/Process.inc
index 7f7e06c855..5d776504fb 100644
--- a/lib/Support/Windows/Process.inc
+++ b/lib/Support/Windows/Process.inc
@@ -11,25 +11,18 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/Allocator.h"
-
#include "Windows.h"
#include <direct.h>
#include <io.h>
#include <malloc.h>
#include <psapi.h>
-#include <Shellapi.h>
#ifdef __MINGW32__
#if (HAVE_LIBPSAPI != 1)
#error "libpsapi.a should be present"
#endif
- #if (HAVE_LIBSHELL32 != 1)
- #error "libshell32.a should be present"
- #endif
#else
-#pragma comment(lib, "psapi.lib")
-#pragma comment(lib, "Shell32.lib")
+ #pragma comment(lib, "psapi.lib")
#endif
//===----------------------------------------------------------------------===//
@@ -158,58 +151,25 @@ Optional<std::string> Process::GetEnv(StringRef Name) {
// Environment variable can be encoded in non-UTF8 encoding, and there's no
// way to know what the encoding is. The only reliable way to look up
// multibyte environment variable is to use GetEnvironmentVariableW().
- SmallVector<wchar_t, MAX_PATH> Buf;
- size_t Size = MAX_PATH;
- do {
- Buf.reserve(Size);
- Size = GetEnvironmentVariableW(&NameUTF16[0], &Buf[0], Buf.capacity());
- if (Size == 0)
- return None;
-
+ std::vector<wchar_t> Buf(16);
+ size_t Size = 0;
+ for (;;) {
+ Size = GetEnvironmentVariableW(&NameUTF16[0], &Buf[0], Buf.size());
+ if (Size < Buf.size())
+ break;
// Try again with larger buffer.
- } while (Size > Buf.capacity());
- Buf.set_size(Size);
+ Buf.resize(Size + 1);
+ }
+ if (Size == 0)
+ return None;
// Convert the result from UTF-16 to UTF-8.
- SmallVector<char, MAX_PATH> Res;
+ SmallVector<char, 128> Res;
if (error_code ec = windows::UTF16ToUTF8(&Buf[0], Size, Res))
return None;
return std::string(&Res[0]);
}
-error_code
-Process::GetArgumentVector(SmallVectorImpl<const char *> &Args,
- ArrayRef<const char *>,
- SpecificBumpPtrAllocator<char> &ArgAllocator) {
- int NewArgCount;
- error_code ec;
-
- wchar_t **UnicodeCommandLine = CommandLineToArgvW(GetCommandLineW(),
- &NewArgCount);
- if (!UnicodeCommandLine)
- return windows_error(::GetLastError());
-
- Args.reserve(NewArgCount);
-
- for (int i = 0; i < NewArgCount; ++i) {
- SmallVector<char, MAX_PATH> NewArgString;
- ec = windows::UTF16ToUTF8(UnicodeCommandLine[i],
- wcslen(UnicodeCommandLine[i]),
- NewArgString);
- if (ec)
- break;
-
- char *Buffer = ArgAllocator.Allocate(NewArgString.size() + 1);
- ::memcpy(Buffer, NewArgString.data(), NewArgString.size() + 1);
- Args.push_back(Buffer);
- }
- LocalFree(UnicodeCommandLine);
- if (ec)
- return ec;
-
- return error_code::success();
-}
-
bool Process::StandardInIsUserInput() {
return FileDescriptorIsDisplayed(0);
}
diff --git a/lib/Support/Windows/Program.inc b/lib/Support/Windows/Program.inc
index e464e2f687..28690852b0 100644
--- a/lib/Support/Windows/Program.inc
+++ b/lib/Support/Windows/Program.inc
@@ -42,39 +42,42 @@ std::string sys::FindProgramByName(const std::string &progName) {
// At this point, the file name is valid and does not contain slashes.
// Let Windows search for it.
- SmallVector<wchar_t, MAX_PATH> progNameUnicode;
- if (windows::UTF8ToUTF16(progName, progNameUnicode))
+ std::string buffer;
+ buffer.resize(MAX_PATH);
+ char *dummy = NULL;
+ DWORD len = SearchPath(NULL, progName.c_str(), ".exe", MAX_PATH,
+ &buffer[0], &dummy);
+
+ // See if it wasn't found.
+ if (len == 0)
return "";
- SmallVector<wchar_t, MAX_PATH> buffer;
- DWORD len = MAX_PATH;
- do {
- buffer.reserve(len);
- len = ::SearchPathW(NULL, progNameUnicode.data(), L".exe",
- buffer.capacity(), buffer.data(), NULL);
+ // See if we got the entire path.
+ if (len < MAX_PATH)
+ return buffer;
- // See if it wasn't found.
- if (len == 0)
- return "";
-
- // Buffer was too small; grow and retry.
- } while (len > buffer.capacity());
+ // Buffer was too small; grow and retry.
+ while (true) {
+ buffer.resize(len+1);
+ DWORD len2 = SearchPath(NULL, progName.c_str(), ".exe", len+1, &buffer[0], &dummy);
- buffer.set_size(len);
- SmallVector<char, MAX_PATH> result;
- if (windows::UTF16ToUTF8(buffer.begin(), buffer.size(), result))
- return "";
+ // It is unlikely the search failed, but it's always possible some file
+ // was added or removed since the last search, so be paranoid...
+ if (len2 == 0)
+ return "";
+ else if (len2 <= len)
+ return buffer;
- return std::string(result.data(), result.size());
+ len = len2;
+ }
}
static HANDLE RedirectIO(const StringRef *path, int fd, std::string* ErrMsg) {
HANDLE h;
if (path == 0) {
- if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fd),
- GetCurrentProcess(), &h,
- 0, TRUE, DUPLICATE_SAME_ACCESS))
- return INVALID_HANDLE_VALUE;
+ DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fd),
+ GetCurrentProcess(), &h,
+ 0, TRUE, DUPLICATE_SAME_ACCESS);
return h;
}
@@ -89,13 +92,9 @@ static HANDLE RedirectIO(const StringRef *path, int fd, std::string* ErrMsg) {
sa.lpSecurityDescriptor = 0;
sa.bInheritHandle = TRUE;
- SmallVector<wchar_t, 128> fnameUnicode;
- if (windows::UTF8ToUTF16(fname, fnameUnicode))
- return INVALID_HANDLE_VALUE;
-
- h = CreateFileW(fnameUnicode.data(), fd ? GENERIC_WRITE : GENERIC_READ,
- FILE_SHARE_READ, &sa, fd == 0 ? OPEN_EXISTING : CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, NULL);
+ h = CreateFile(fname.c_str(), fd ? GENERIC_WRITE : GENERIC_READ,
+ FILE_SHARE_READ, &sa, fd == 0 ? OPEN_EXISTING : CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE) {
MakeErrMsg(ErrMsg, std::string(fname) + ": Can't open file for " +
(fd ? "input: " : "output: "));
@@ -219,28 +218,34 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
*p = 0;
// The pointer to the environment block for the new process.
- std::vector<wchar_t> EnvBlock;
+ OwningArrayPtr<char> envblock;
if (envp) {
// An environment block consists of a null-terminated block of
// null-terminated strings. Convert the array of environment variables to
// an environment block by concatenating them.
- for (unsigned i = 0; envp[i]; ++i) {
- SmallVector<wchar_t, MAX_PATH> EnvString;
- if (error_code ec = windows::UTF8ToUTF16(envp[i], EnvString)) {
- SetLastError(ec.value());
- MakeErrMsg(ErrMsg, "Unable to convert environment variable to UTF-16");
- return false;
- }
- EnvBlock.insert(EnvBlock.end(), EnvString.begin(), EnvString.end());
- EnvBlock.push_back(0);
+ // First, determine the length of the environment block.
+ len = 0;
+ for (unsigned i = 0; envp[i]; i++)
+ len += strlen(envp[i]) + 1;
+
+ // Now build the environment block.
+ envblock.reset(new char[len+1]);
+ p = envblock.get();
+
+ for (unsigned i = 0; envp[i]; i++) {
+ const char *ev = envp[i];
+ size_t len = strlen(ev) + 1;
+ memcpy(p, ev, len);
+ p += len;
}
- EnvBlock.push_back(0);
+
+ *p = 0;
}
// Create a child process.
- STARTUPINFOW si;
+ STARTUPINFO si;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
si.hStdInput = INVALID_HANDLE_VALUE;
@@ -264,14 +269,9 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
if (redirects[1] && redirects[2] && *(redirects[1]) == *(redirects[2])) {
// If stdout and stderr should go to the same place, redirect stderr
// to the handle already open for stdout.
- if (!DuplicateHandle(GetCurrentProcess(), si.hStdOutput,
- GetCurrentProcess(), &si.hStdError,
- 0, TRUE, DUPLICATE_SAME_ACCESS)) {
- CloseHandle(si.hStdInput);
- CloseHandle(si.hStdOutput);
- MakeErrMsg(ErrMsg, "can't dup stderr to stdout");
- return false;
- }
+ DuplicateHandle(GetCurrentProcess(), si.hStdOutput,
+ GetCurrentProcess(), &si.hStdError,
+ 0, TRUE, DUPLICATE_SAME_ACCESS);
} else {
// Just redirect stderr
si.hStdError = RedirectIO(redirects[2], 2, ErrMsg);
@@ -289,27 +289,9 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
fflush(stdout);
fflush(stderr);
-
- SmallVector<wchar_t, MAX_PATH> ProgramUtf16;
- if (error_code ec = windows::UTF8ToUTF16(Program, ProgramUtf16)) {
- SetLastError(ec.value());
- MakeErrMsg(ErrMsg,
- std::string("Unable to convert application name to UTF-16"));
- return false;
- }
-
- SmallVector<wchar_t, MAX_PATH> CommandUtf16;
- if (error_code ec = windows::UTF8ToUTF16(command.get(), CommandUtf16)) {
- SetLastError(ec.value());
- MakeErrMsg(ErrMsg,
- std::string("Unable to convert command-line to UTF-16"));
- return false;
- }
-
- BOOL rc = CreateProcessW(ProgramUtf16.data(), CommandUtf16.data(), 0, 0,
- TRUE, CREATE_UNICODE_ENVIRONMENT,
- EnvBlock.empty() ? 0 : EnvBlock.data(), 0, &si,
- &pi);
+ std::string ProgramStr = Program;
+ BOOL rc = CreateProcess(ProgramStr.c_str(), command.get(), NULL, NULL, TRUE,
+ 0, envblock.get(), NULL, &si, &pi);
DWORD err = GetLastError();
// Regardless of whether the process got created or not, we are done with
@@ -322,7 +304,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
if (!rc) {
SetLastError(err);
MakeErrMsg(ErrMsg, std::string("Couldn't execute program '") +
- Program.str() + "'");
+ ProgramStr + "'");
return false;
}
diff --git a/lib/Support/Windows/Signals.inc b/lib/Support/Windows/Signals.inc
index 2b4a66d008..bce83b9686 100644
--- a/lib/Support/Windows/Signals.inc
+++ b/lib/Support/Windows/Signals.inc
@@ -135,7 +135,7 @@ typedef PVOID (WINAPI *fpSymFunctionTableAccess64)(HANDLE, DWORD64);
static fpSymFunctionTableAccess64 SymFunctionTableAccess64;
static bool load64BitDebugHelp(void) {
- HMODULE hLib = ::LoadLibrary(TEXT("Dbghelp.dll"));
+ HMODULE hLib = ::LoadLibrary("Dbghelp.dll");
if (hLib) {
StackWalk64 = (fpStackWalk64)
::GetProcAddress(hLib, "StackWalk64");
diff --git a/lib/Support/Windows/Windows.h b/lib/Support/Windows/Windows.h
index 657ae4fc83..1236fe5652 100644
--- a/lib/Support/Windows/Windows.h
+++ b/lib/Support/Windows/Windows.h
@@ -31,6 +31,7 @@
#include "llvm/Support/system_error.h"
#include <windows.h>
#include <wincrypt.h>
+#include <shlobj.h>
#include <cassert>
#include <string>
#include <vector>