cameron314 updated this revision to Diff 50447.
cameron314 added a comment.
Here we go! http://reviews.llvm.org/D17549 has been committed, so I've rebased
this patch onto that latest version (r263233).
http://reviews.llvm.org/D17107
Files:
/lldb/trunkcmake/modules/LLDBConfig.cmake
/lldb/trunkinclude/lldb/Host/FileSystem.h
/lldb/trunkinclude/lldb/Host/posix/HostInfoPosix.h
/lldb/trunkinclude/lldb/Host/windows/HostInfoWindows.h
/lldb/trunkpackages/Python/lldbsuite/test/dotest.py
/lldb/trunksource/Commands/CommandCompletions.cpp
/lldb/trunksource/Core/ConnectionSharedMemory.cpp
/lldb/trunksource/Core/Disassembler.cpp
/lldb/trunksource/Host/common/File.cpp
/lldb/trunksource/Host/common/FileSpec.cpp
/lldb/trunksource/Host/posix/FileSystem.cpp
/lldb/trunksource/Host/posix/HostInfoPosix.cpp
/lldb/trunksource/Host/windows/ConnectionGenericFileWindows.cpp
/lldb/trunksource/Host/windows/FileSystem.cpp
/lldb/trunksource/Host/windows/Host.cpp
/lldb/trunksource/Host/windows/HostInfoWindows.cpp
/lldb/trunksource/Host/windows/HostProcessWindows.cpp
/lldb/trunksource/Host/windows/PipeWindows.cpp
/lldb/trunksource/Host/windows/ProcessLauncherWindows.cpp
/lldb/trunksource/Host/windows/Windows.cpp
/lldb/trunksource/Plugins/Process/Windows/Live/DebuggerThread.cpp
/lldb/trunksource/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
/lldb/trunksource/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
/lldb/trunksource/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
/lldb/trunksource/Target/ProcessLaunchInfo.cpp
/lldb/trunktools/driver/Driver.cpp
/lldb/trunktools/driver/Platform.h
/lldb/trunktools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
/lldb/trunktools/lldb-mi/MIUtilFileStd.cpp
/lldb/trunktools/lldb-mi/Platform.h
Index: /lldb/trunktools/lldb-mi/Platform.h
===================================================================
--- /dev/null
+++ /lldb/trunktools/lldb-mi/Platform.h
@@ -60,7 +60,7 @@
typedef long pid_t;
#define STDIN_FILENO 0
-#define PATH_MAX MAX_PATH
+#define PATH_MAX 32768
#define snprintf _snprintf
extern int ioctl(int d, int request, ...);
Index: /lldb/trunktools/lldb-mi/MIUtilFileStd.cpp
===================================================================
--- /dev/null
+++ /lldb/trunktools/lldb-mi/MIUtilFileStd.cpp
@@ -17,6 +17,8 @@
#include "MIUtilFileStd.h"
#include "MICmnResources.h"
+#include "llvm/Support/ConvertUTF.h"
+
//++ ------------------------------------------------------------------------------------
// Details: CMIUtilFileStd constructor.
// Type: Method.
@@ -82,7 +84,14 @@
m_pFileHandle = ::fopen(vFileNamePath.c_str(), "wb");
#else
// Open a file with exclusive write and shared read permissions
- m_pFileHandle = ::_fsopen(vFileNamePath.c_str(), "wb", _SH_DENYWR);
+ std::wstring path;
+ if (llvm::ConvertUTF8toWide(vFileNamePath.c_str(), path))
+ m_pFileHandle = ::_wfsopen(path.c_str(), L"wb", _SH_DENYWR);
+ else
+ {
+ errno = EINVAL;
+ m_pFileHandle = nullptr;
+ }
#endif // !defined( _MSC_VER )
if (m_pFileHandle == nullptr)
@@ -222,7 +231,14 @@
return false;
FILE *pTmp = nullptr;
+#ifdef _WIN32
+ std::wstring path;
+ if (!llvm::ConvertUTF8toWide(vFileNamePath.c_str(), path))
+ return false;
+ pTmp = ::_wfopen(path.c_str(), L"wb");
+#else
pTmp = ::fopen(vFileNamePath.c_str(), "wb");
+#endif
if (pTmp != nullptr)
{
::fclose(pTmp);
Index: /lldb/trunktools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
===================================================================
--- /dev/null
+++ /lldb/trunktools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
@@ -27,6 +27,7 @@
#include "MICmnMIValueTuple.h"
#include "MICmdData.h"
#include "MICmnLLDBUtilSBValue.h"
+#include "Platform.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmnLLDBDebugSessionInfo constructor.
@@ -614,7 +615,7 @@
{
lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame);
- static char pBuffer[MAX_PATH];
+ static char pBuffer[PATH_MAX];
const MIuint nBytes = rFrame.GetLineEntry().GetFileSpec().GetPath(&pBuffer[0], sizeof(pBuffer));
MIunused(nBytes);
CMIUtilString strResolvedPath(&pBuffer[0]);
Index: /lldb/trunktools/driver/Platform.h
===================================================================
--- /dev/null
+++ /lldb/trunktools/driver/Platform.h
@@ -81,7 +81,7 @@
typedef long pid_t;
#define snprintf _snprintf
extern sighandler_t signal( int sig, sighandler_t );
- #define PATH_MAX MAX_PATH
+ #define PATH_MAX 32768
#endif
#define STDIN_FILENO 0
Index: /lldb/trunktools/driver/Driver.cpp
===================================================================
--- /dev/null
+++ /lldb/trunktools/driver/Driver.cpp
@@ -42,6 +42,7 @@
#include "lldb/API/SBTarget.h"
#include "lldb/API/SBThread.h"
#include "lldb/API/SBProcess.h"
+#include "llvm/Support/ConvertUTF.h"
#if !defined(__APPLE__)
#include "llvm/Support/DataTypes.h"
@@ -1298,14 +1299,30 @@
}
int
-main (int argc, char const *argv[], const char *envp[])
+#ifdef WIN32
+wmain(int argc, wchar_t const *wargv[])
+#else
+main (int argc, char const *argv[])
+#endif
{
#ifdef _MSC_VER
// disable buffering on windows
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stdin , NULL, _IONBF, 0);
#endif
+#ifdef _WIN32
+ // Convert wide arguments to UTF-8
+ std::vector<std::string> argvStrings(argc);
+ std::vector<const char*> argvPointers(argc);
+ for (int i = 0; i != argc; ++i)
+ {
+ llvm::convertWideToUTF8(wargv[i], argvStrings[i]);
+ argvPointers[i] = argvStrings[i].c_str();
+ }
+ const char** argv = argvPointers.data();
+#endif
+
SBDebugger::Initialize();
SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
Index: /lldb/trunksource/Target/ProcessLaunchInfo.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Target/ProcessLaunchInfo.cpp
@@ -16,11 +16,18 @@
#include "lldb/Host/Config.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
+#include "lldb/Host/HostInfo.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Target/FileAction.h"
#include "lldb/Target/Target.h"
+#include "llvm/Support/ConvertUTF.h"
+
+#if !defined(_WIN32)
+#include <limits.h>
+#endif
+
using namespace lldb;
using namespace lldb_private;
@@ -449,8 +456,8 @@
if (cwd && cwd[0])
new_path += cwd;
}
- const char *curr_path = getenv("PATH");
- if (curr_path)
+ std::string curr_path;
+ if (HostInfo::GetEnvironmentVar("PATH", curr_path))
{
if (new_path.size() > empty_path_len)
new_path += ':';
Index: /lldb/trunksource/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -19,8 +19,11 @@
#include "lldb/Core/Stream.h"
#include "lldb/Host/File.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "llvm/Support/ConvertUTF.h"
+
#include <stdio.h>
#include "llvm/ADT/StringSwitch.h"
@@ -1162,9 +1165,7 @@
PythonFile::PythonFile(const char *path, const char *mode)
{
- FILE *fp = nullptr;
- fp = fopen(path, mode);
- lldb_private::File file(fp, true);
+ lldb_private::File file(path, GetOptionsFromMode(mode));
Reset(file, mode);
}
Index: /lldb/trunksource/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
@@ -370,14 +370,22 @@
{
Error error;
const char *file = m_core_file.GetCString();
- m_dump_file = ::CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ std::wstring wfile;
+ if (!llvm::ConvertUTF8toWide(file, wfile))
+ {
+ error.SetErrorString("Error converting path to UTF-16");
+ return error;
+ }
+ m_dump_file = ::CreateFileW(wfile.c_str(), GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL);
if (m_dump_file == INVALID_HANDLE_VALUE)
{
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
}
- m_mapping = ::CreateFileMapping(m_dump_file, NULL, PAGE_READONLY, 0, 0, NULL);
+ m_mapping = ::CreateFileMappingW(m_dump_file, NULL, PAGE_READONLY, 0, 0, NULL);
if (m_mapping == NULL)
{
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
@@ -509,7 +517,7 @@
auto source_start = reinterpret_cast<const UTF16 *>(md_string->Buffer);
const auto source_length = ::wcslen(md_string->Buffer);
const auto source_end = source_start + source_length;
- result.resize(4 * source_length); // worst case length
+ result.resize(UNI_MAX_UTF8_BYTES_PER_CODE_POINT * source_length); // worst case length
auto result_start = reinterpret_cast<UTF8 *>(&result[0]);
const auto result_end = result_start + result.size();
ConvertUTF16toUTF8(&source_start, source_end, &result_start, result_end, strictConversion);
Index: /lldb/trunksource/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
@@ -47,6 +47,7 @@
#include "ProcessWindowsLive.h"
#include "TargetThreadWindowsLive.h"
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
@@ -61,17 +62,19 @@
std::string
GetProcessExecutableName(HANDLE process_handle)
{
- std::vector<char> file_name;
+ std::vector<wchar_t> file_name;
DWORD file_name_size = MAX_PATH; // first guess, not an absolute limit
DWORD copied = 0;
do
{
file_name_size *= 2;
file_name.resize(file_name_size);
- copied = ::GetModuleFileNameEx(process_handle, NULL, file_name.data(), file_name_size);
+ copied = ::GetModuleFileNameExW(process_handle, NULL, file_name.data(), file_name_size);
} while (copied >= file_name_size);
file_name.resize(copied);
- return std::string(file_name.begin(), file_name.end());
+ std::string result;
+ llvm::convertWideToUTF8(file_name.data(), result);
+ return result;
}
std::string
Index: /lldb/trunksource/Plugins/Process/Windows/Live/DebuggerThread.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Plugins/Process/Windows/Live/DebuggerThread.cpp
@@ -27,6 +27,7 @@
#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/raw_ostream.h"
using namespace lldb;
@@ -484,13 +485,15 @@
return DBG_CONTINUE;
}
- std::vector<char> buffer(1);
- DWORD required_size = GetFinalPathNameByHandle(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
+ std::vector<wchar_t> buffer(1);
+ DWORD required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
if (required_size > 0)
{
buffer.resize(required_size + 1);
- required_size = GetFinalPathNameByHandle(info.hFile, &buffer[0], required_size + 1, VOLUME_NAME_DOS);
- llvm::StringRef path_str(&buffer[0]);
+ required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0], required_size, VOLUME_NAME_DOS);
+ std::string path_str_utf8;
+ llvm::convertWideToUTF8(buffer.data(), path_str_utf8);
+ llvm::StringRef path_str = path_str_utf8;
const char *path = path_str.data();
if (path_str.startswith("\\\\?\\"))
path += 4;
Index: /lldb/trunksource/Host/windows/Windows.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Host/windows/Windows.cpp
@@ -12,6 +12,8 @@
#include "lldb/Host/windows/windows.h"
#include "lldb/Host/windows/win32.h"
+#include "llvm/Support/ConvertUTF.h"
+
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
@@ -27,6 +29,33 @@
int _chdir(const char *path);
}
+namespace
+{
+ bool utf8ToWide(const char* utf8, wchar_t* buf, size_t bufSize)
+ {
+ const UTF8* sourceStart = reinterpret_cast<const UTF8*>(utf8);
+ size_t sourceLen = strlen(utf8) + 1 /* convert null too */;
+ UTF16* target = reinterpret_cast<UTF16*>(buf);
+ ConversionFlags flags = strictConversion;
+ return ConvertUTF8toUTF16(
+ &sourceStart, sourceStart + sourceLen,
+ &target, target + bufSize, flags) ==
+ conversionOK;
+ }
+
+ bool wideToUtf8(const wchar_t* wide, char* buf, size_t bufSize)
+ {
+ const UTF16* sourceStart = reinterpret_cast<const UTF16*>(wide);
+ size_t sourceLen = wcslen(wide) + 1 /* convert null too */;
+ UTF8* target = reinterpret_cast<UTF8*>(buf);
+ ConversionFlags flags = strictConversion;
+ return ConvertUTF16toUTF8(
+ &sourceStart, sourceStart + sourceLen,
+ &target, target + bufSize, flags) ==
+ conversionOK;
+ }
+}
+
int vasprintf(char **ret, const char *fmt, va_list ap)
{
char *buf;
@@ -75,81 +104,90 @@
char* realpath(const char * name, char * resolved)
{
- char *retname = NULL; /* we will return this, if we fail */
+ char *retname = NULL;
/* SUSv3 says we must set `errno = EINVAL', and return NULL,
* if `name' is passed as a NULL pointer.
*/
-
if (name == NULL)
+ {
errno = EINVAL;
+ return NULL;
+ }
/* Otherwise, `name' must refer to a readable filesystem object,
* if we are going to resolve its absolute path name.
*/
-
- else if (access(name, 4) == 0)
+ wchar_t wideNameBuffer[PATH_MAX];
+ wchar_t* wideName = wideNameBuffer;
+ if (!utf8ToWide(name, wideName, PATH_MAX))
{
- /* If `name' didn't point to an existing entity,
- * then we don't get to here; we simply fall past this block,
- * returning NULL, with `errno' appropriately set by `access'.
- *
- * When we _do_ get to here, then we can use `_fullpath' to
- * resolve the full path for `name' into `resolved', but first,
- * check that we have a suitable buffer, in which to return it.
- */
+ errno = EINVAL;
+ return NULL;
+ }
- if ((retname = resolved) == NULL)
- {
- /* Caller didn't give us a buffer, so we'll exercise the
- * option granted by SUSv3, and allocate one.
- *
- * `_fullpath' would do this for us, but it uses `malloc', and
- * Microsoft's implementation doesn't set `errno' on failure.
- * If we don't do this explicitly ourselves, then we will not
- * know if `_fullpath' fails on `malloc' failure, or for some
- * other reason, and we want to set `errno = ENOMEM' for the
- * `malloc' failure case.
- */
-
- retname = (char*) malloc(_MAX_PATH);
- }
+ if (_waccess(wideName, 4) != 0)
+ return NULL;
+
+ /* If `name' didn't point to an existing entity,
+ * then we don't get to here; we simply fall past this block,
+ * returning NULL, with `errno' appropriately set by `access'.
+ *
+ * When we _do_ get to here, then we can use `_fullpath' to
+ * resolve the full path for `name' into `resolved', but first,
+ * check that we have a suitable buffer, in which to return it.
+ */
- /* By now, we should have a valid buffer.
- * If we don't, then we know that `malloc' failed,
- * so we can set `errno = ENOMEM' appropriately.
+ if ((retname = resolved) == NULL)
+ {
+ /* Caller didn't give us a buffer, so we'll exercise the
+ * option granted by SUSv3, and allocate one.
+ *
+ * `_fullpath' would do this for us, but it uses `malloc', and
+ * Microsoft's implementation doesn't set `errno' on failure.
+ * If we don't do this explicitly ourselves, then we will not
+ * know if `_fullpath' fails on `malloc' failure, or for some
+ * other reason, and we want to set `errno = ENOMEM' for the
+ * `malloc' failure case.
*/
+ retname = (char*) malloc(PATH_MAX);
if (retname == NULL)
+ {
errno = ENOMEM;
+ return NULL;
+ }
+ }
- /* Otherwise, when we do have a valid buffer,
- * `_fullpath' should only fail if the path name is too long.
- */
+ /* Otherwise, when we do have a valid buffer,
+ * `_fullpath' should only fail if the path name is too long.
+ */
- else if ((retname = _fullpath(retname, name, _MAX_PATH)) == NULL)
- errno = ENAMETOOLONG;
+ wchar_t wideFullPathBuffer[PATH_MAX];
+ wchar_t* wideFullPath;
+ if ((wideFullPath = _wfullpath(wideFullPathBuffer, wideName, PATH_MAX)) == NULL)
+ {
+ errno = ENAMETOOLONG;
+ return NULL;
}
- /* By the time we get to here,
- * `retname' either points to the required resolved path name,
- * or it is NULL, with `errno' set appropriately, either of which
- * is our required return condition.
- */
+ // Do a LongPath<->ShortPath roundtrip so that case is resolved by OS
+ // FIXME: Check for failure
+ size_t initialLength = wcslen(wideFullPath);
+ GetShortPathNameW(wideFullPath, wideNameBuffer, PATH_MAX);
+ GetLongPathNameW(wideNameBuffer, wideFullPathBuffer, initialLength + 1);
- if (retname != NULL)
+ // Convert back to UTF-8
+ if (!wideToUtf8(wideFullPathBuffer, retname, PATH_MAX))
{
- // Do a LongPath<->ShortPath roundtrip so that case is resolved by OS
- int initialLength = strlen(retname);
- TCHAR buffer[MAX_PATH];
- GetShortPathName(retname, buffer, MAX_PATH);
- GetLongPathName(buffer, retname, initialLength + 1);
-
- // Force drive to be upper case
- if (retname[1] == ':')
- retname[0] = toupper(retname[0]);
+ errno = EINVAL;
+ return NULL;
}
+ // Force drive to be upper case
+ if (retname[1] == ':')
+ retname[0] = toupper(retname[0]);
+
return retname;
}
@@ -167,7 +205,27 @@
// use _getcwd() instead of GetCurrentDirectory() because it updates errno
char* getcwd(char* path, int max)
{
- return _getcwd(path, max);
+ assert(path == NULL || max <= PATH_MAX);
+ wchar_t wpath[PATH_MAX];
+ if (wchar_t* wresult = _wgetcwd(wpath, PATH_MAX))
+ {
+ // Caller is allowed to pass in NULL for `path`.
+ // In that case, we're supposed to allocate a
+ // buffer on the caller's behalf.
+ if (path == NULL)
+ {
+ max = UNI_MAX_UTF8_BYTES_PER_CODE_POINT * wcslen(wresult) + 1;
+ path = (char*)malloc(max);
+ if (path == NULL)
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+ }
+ if (wideToUtf8(wresult, path, max))
+ return path;
+ }
+ return NULL;
}
// use _chdir() instead of SetCurrentDirectory() because it updates errno
Index: /lldb/trunksource/Host/windows/ProcessLauncherWindows.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Host/windows/ProcessLauncherWindows.cpp
@@ -11,6 +11,9 @@
#include "lldb/Host/windows/ProcessLauncherWindows.h"
#include "lldb/Target/ProcessLaunchInfo.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/ADT/SmallVector.h"
+
#include <string>
#include <vector>
@@ -25,20 +28,19 @@
if (env.GetArgumentCount() == 0)
return;
- int bytes = 0;
- for (int i = 0; i < env.GetArgumentCount(); ++i)
- bytes += strlen(env.GetArgumentAtIndex(i)) + sizeof(char);
- bytes += sizeof(char);
- buffer.resize(bytes);
- char *cur_entry = &buffer[0];
+ // Environment buffer is a null terminated list of null terminated strings
for (int i = 0; i < env.GetArgumentCount(); ++i)
{
- ::strcpy(cur_entry, env.GetArgumentAtIndex(i));
- cur_entry += strlen(cur_entry) + sizeof(char);
+ std::wstring warg;
+ if (llvm::ConvertUTF8toWide(env.GetArgumentAtIndex(i), warg))
+ {
+ buffer.insert(buffer.end(), (char*)warg.c_str(),
+ (char*)(warg.c_str() + warg.size() + 1));
+ }
}
- // Environment buffer is a null terminated list of null terminated
- // strings, so it is terminated by two null bytes.
- buffer.back() = 0;
+ // One null wchar_t (to end the block) is two null bytes
+ buffer.push_back(0);
+ buffer.push_back(0);
}
}
@@ -70,7 +72,7 @@
startupinfo.wShowWindow = SW_HIDE;
}
- DWORD flags = CREATE_NEW_CONSOLE;
+ DWORD flags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;
if (launch_info.GetFlags().Test(eLaunchFlagDebug))
flags |= DEBUG_ONLY_THIS_PROCESS;
@@ -82,8 +84,16 @@
executable = launch_info.GetExecutableFile().GetPath();
launch_info.GetArguments().GetQuotedCommandString(commandLine);
- BOOL result = ::CreateProcessA(executable.c_str(), const_cast<char *>(commandLine.c_str()), NULL, NULL, TRUE, flags,
- env_block, launch_info.GetWorkingDirectory().GetCString(), &startupinfo, &pi);
+
+ std::wstring wexecutable, wcommandLine, wworkingDirectory;
+ llvm::ConvertUTF8toWide(executable, wexecutable);
+ llvm::ConvertUTF8toWide(commandLine, wcommandLine);
+ llvm::ConvertUTF8toWide(launch_info.GetWorkingDirectory().GetCString(), wworkingDirectory);
+
+ wcommandLine.resize(PATH_MAX); // Needs to be over-allocated because CreateProcessW can modify it
+ BOOL result = ::CreateProcessW(wexecutable.c_str(), &wcommandLine[0], NULL, NULL, TRUE, flags,
+ env_block, wworkingDirectory.size() == 0 ? NULL : wworkingDirectory.c_str(),
+ &startupinfo, &pi);
if (result)
{
// Do not call CloseHandle on pi.hProcess, since we want to pass that back through the HostProcess.
@@ -131,6 +141,8 @@
flags = FILE_FLAG_WRITE_THROUGH;
}
- HANDLE result = ::CreateFile(path, access, share, &secattr, create, flags, NULL);
+ std::wstring wpath;
+ llvm::ConvertUTF8toWide(path, wpath);
+ HANDLE result = ::CreateFileW(wpath.c_str(), access, share, &secattr, create, flags, NULL);
return (result == INVALID_HANDLE_VALUE) ? NULL : result;
}
Index: /lldb/trunksource/Host/windows/PipeWindows.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Host/windows/PipeWindows.cpp
@@ -74,7 +74,7 @@
// Always open for overlapped i/o. We implement blocking manually in Read and Write.
DWORD read_mode = FILE_FLAG_OVERLAPPED;
m_read =
- ::CreateNamedPipe(pipe_path.c_str(), PIPE_ACCESS_INBOUND | read_mode, PIPE_TYPE_BYTE | PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL);
+ ::CreateNamedPipeA(pipe_path.c_str(), PIPE_ACCESS_INBOUND | read_mode, PIPE_TYPE_BYTE | PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL);
if (INVALID_HANDLE_VALUE == m_read)
return Error(::GetLastError(), eErrorTypeWin32);
m_read_fd = _open_osfhandle((intptr_t)m_read, _O_RDONLY);
@@ -153,7 +153,7 @@
if (is_read)
{
- m_read = ::CreateFile(pipe_path.c_str(), GENERIC_READ, 0, &attributes, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+ m_read = ::CreateFileA(pipe_path.c_str(), GENERIC_READ, 0, &attributes, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (INVALID_HANDLE_VALUE == m_read)
return Error(::GetLastError(), eErrorTypeWin32);
@@ -164,7 +164,7 @@
}
else
{
- m_write = ::CreateFile(pipe_path.c_str(), GENERIC_WRITE, 0, &attributes, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+ m_write = ::CreateFileA(pipe_path.c_str(), GENERIC_WRITE, 0, &attributes, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (INVALID_HANDLE_VALUE == m_write)
return Error(::GetLastError(), eErrorTypeWin32);
Index: /lldb/trunksource/Host/windows/HostProcessWindows.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Host/windows/HostProcessWindows.cpp
@@ -14,6 +14,7 @@
#include "lldb/Host/windows/HostProcessWindows.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/ConvertUTF.h"
#include <Psapi.h>
@@ -70,9 +71,15 @@
if (m_process == nullptr)
error.SetError(ERROR_INVALID_HANDLE, lldb::eErrorTypeWin32);
- char path[MAX_PATH] = { 0 };
- if (::GetProcessImageFileName(m_process, path, llvm::array_lengthof(path)))
- file_spec.SetFile(path, false);
+ std::vector<wchar_t> wpath(PATH_MAX);
+ if (::GetProcessImageFileNameW(m_process, wpath.data(), wpath.size()))
+ {
+ std::string path;
+ if (llvm::convertWideToUTF8(wpath.data(), path))
+ file_spec.SetFile(path, false);
+ else
+ error.SetErrorString("Error converting path to UTF-8");
+ }
else
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
Index: /lldb/trunksource/Host/windows/HostInfoWindows.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Host/windows/HostInfoWindows.cpp
@@ -15,6 +15,7 @@
#include "lldb/Host/windows/HostInfoWindows.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Path.h"
@@ -92,31 +93,34 @@
bool
HostInfoWindows::GetHostname(std::string &s)
{
- char buffer[MAX_COMPUTERNAME_LENGTH + 1];
+ wchar_t buffer[MAX_COMPUTERNAME_LENGTH + 1];
DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
- if (!::GetComputerName(buffer, &dwSize))
+ if (!::GetComputerNameW(buffer, &dwSize))
return false;
- s.assign(buffer, buffer + dwSize);
- return true;
+ return llvm::convertWideToUTF8(buffer, s);
}
FileSpec
HostInfoWindows::GetProgramFileSpec()
{
static std::once_flag g_once_flag;
std::call_once(g_once_flag, []() {
- char buffer[PATH_MAX];
- ::GetModuleFileName(NULL, buffer, sizeof(buffer));
- m_program_filespec.SetFile(buffer, false);
+ std::vector<wchar_t> buffer(PATH_MAX);
+ ::GetModuleFileNameW(NULL, buffer.data(), buffer.size());
+ std::string path;
+ llvm::convertWideToUTF8(buffer.data(), path);
+ m_program_filespec.SetFile(path, false);
});
return m_program_filespec;
}
FileSpec
HostInfoWindows::GetDefaultShell()
{
- return FileSpec(::getenv("ComSpec"), false);
+ std::string shell;
+ GetEnvironmentVar("ComSpec", shell);
+ return FileSpec(shell, false);
}
bool
@@ -132,3 +136,15 @@
file_spec.GetDirectory().SetString(path.c_str());
return true;
}
+
+bool
+HostInfoWindows::GetEnvironmentVar(const std::string &var_name, std::string &var)
+{
+ std::wstring wvar_name;
+ if (!llvm::ConvertUTF8toWide(var_name, wvar_name))
+ return false;
+
+ if (const wchar_t *wvar = _wgetenv(wvar_name.c_str()))
+ return llvm::convertWideToUTF8(wvar, var);
+ return false;
+}
Index: /lldb/trunksource/Host/windows/Host.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Host/windows/Host.cpp
@@ -26,6 +26,8 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StructuredData.h"
+#include "llvm/Support/ConvertUTF.h"
+
// Windows includes
#include <TlHelp32.h>
@@ -68,12 +70,11 @@
bool GetExecutableForProcess(const AutoHandle &handle, std::string &path)
{
// Get the process image path. MAX_PATH isn't long enough, paths can actually be up to 32KB.
- std::vector<char> buffer(32768);
+ std::vector<wchar_t> buffer(PATH_MAX);
DWORD dwSize = buffer.size();
- if (!::QueryFullProcessImageNameA(handle.get(), 0, &buffer[0], &dwSize))
+ if (!::QueryFullProcessImageNameW(handle.get(), 0, &buffer[0], &dwSize))
return false;
- path.assign(&buffer[0]);
- return true;
+ return llvm::convertWideToUTF8(buffer.data(), path);
}
void GetProcessExecutableAndTriple(const AutoHandle &handle, ProcessInstanceInfo &process)
@@ -156,15 +157,17 @@
if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)host_addr, &hmodule))
return module_filespec;
- std::vector<char> buffer(MAX_PATH);
+ std::vector<wchar_t> buffer(PATH_MAX);
DWORD chars_copied = 0;
do {
- chars_copied = ::GetModuleFileName(hmodule, &buffer[0], buffer.size());
+ chars_copied = ::GetModuleFileNameW(hmodule, &buffer[0], buffer.size());
if (chars_copied == buffer.size() && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
buffer.resize(buffer.size() * 2);
} while (chars_copied >= buffer.size());
-
- module_filespec.SetFile(&buffer[0], false);
+ std::string path;
+ if (!llvm::convertWideToUTF8(buffer.data(), path))
+ return module_filespec;
+ module_filespec.SetFile(path, false);
return module_filespec;
}
@@ -177,23 +180,25 @@
if (!snapshot.IsValid())
return 0;
- PROCESSENTRY32 pe = {0};
- pe.dwSize = sizeof(PROCESSENTRY32);
- if (Process32First(snapshot.get(), &pe))
+ PROCESSENTRY32W pe = {0};
+ pe.dwSize = sizeof(PROCESSENTRY32W);
+ if (Process32FirstW(snapshot.get(), &pe))
{
do
{
AutoHandle handle(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pe.th32ProcessID), nullptr);
ProcessInstanceInfo process;
- process.SetExecutableFile(FileSpec(pe.szExeFile, false), true);
+ std::string exeFile;
+ llvm::convertWideToUTF8(pe.szExeFile, exeFile);
+ process.SetExecutableFile(FileSpec(exeFile, false), true);
process.SetProcessID(pe.th32ProcessID);
process.SetParentProcessID(pe.th32ParentProcessID);
GetProcessExecutableAndTriple(handle, process);
if (match_info.MatchAllProcesses() || match_info.Matches(process))
process_infos.Append(process);
- } while (Process32Next(snapshot.get(), &pe));
+ } while (Process32NextW(snapshot.get(), &pe));
}
return process_infos.GetSize();
}
@@ -312,15 +317,21 @@
{
// The environment block on Windows is a contiguous buffer of NULL terminated strings,
// where the end of the environment block is indicated by two consecutive NULLs.
- LPCH environment_block = ::GetEnvironmentStrings();
+ LPWCH environment_block = ::GetEnvironmentStringsW();
env.Clear();
- while (*environment_block != '\0')
+ while (*environment_block != L'\0')
{
- llvm::StringRef current_var(environment_block);
+ std::string current_var;
+ auto current_var_size = wcslen(environment_block) + 1;
+ if (!llvm::convertWideToUTF8(environment_block, current_var))
+ {
+ environment_block += current_var_size;
+ continue;
+ }
if (current_var[0] != '=')
env.AppendString(current_var);
- environment_block += current_var.size()+1;
+ environment_block += current_var_size;
}
return env.GetSize();
}
Index: /lldb/trunksource/Host/windows/FileSystem.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Host/windows/FileSystem.cpp
@@ -15,13 +15,18 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/windows/AutoHandle.h"
+
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/FileSystem.h"
using namespace lldb_private;
const char *
FileSystem::DEV_NULL = "nul";
+const char *
+FileSystem::PATH_CONVERSION_ERROR = "Error converting path between UTF-8 and native encoding";
+
FileSpec::PathSyntax
FileSystem::GetNativePathSyntax()
{
@@ -47,25 +52,32 @@
FileSystem::DeleteDirectory(const FileSpec &file_spec, bool recurse)
{
Error error;
+ std::wstring path_buffer;
+ if (!llvm::ConvertUTF8toWide(file_spec.GetPath(), path_buffer))
+ {
+ error.SetErrorString(PATH_CONVERSION_ERROR);
+ return error;
+ }
if (!recurse)
{
- BOOL result = ::RemoveDirectory(file_spec.GetCString());
+ BOOL result = ::RemoveDirectoryW(path_buffer.c_str());
if (!result)
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
}
else
{
// SHFileOperation() accepts a list of paths, and so must be double-null-terminated to
- // indicate the end of the list.
- std::string path_buffer{file_spec.GetPath()};
+ // indicate the end of the list. The first null terminator is there only in the backing
+ // store but not the actual vector contents, and so we need to push twice.
+ path_buffer.push_back(0);
path_buffer.push_back(0);
- SHFILEOPSTRUCT shfos = {0};
+ SHFILEOPSTRUCTW shfos = {0};
shfos.wFunc = FO_DELETE;
- shfos.pFrom = path_buffer.c_str();
+ shfos.pFrom = (LPCWSTR)path_buffer.data();
shfos.fFlags = FOF_NO_UI;
- int result = ::SHFileOperation(&shfos);
+ int result = ::SHFileOperationW(&shfos);
// TODO(zturner): Correctly handle the intricacies of SHFileOperation return values.
if (result != 0)
error.SetErrorStringWithFormat("SHFileOperation failed");
@@ -121,15 +133,23 @@
FileSystem::Hardlink(const FileSpec &src, const FileSpec &dst)
{
Error error;
- if (!::CreateHardLink(src.GetCString(), dst.GetCString(), nullptr))
+ std::wstring wsrc, wdst;
+ if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc) ||
+ !llvm::ConvertUTF8toWide(dst.GetCString(), wdst))
+ error.SetErrorString(PATH_CONVERSION_ERROR);
+ else if (!::CreateHardLinkW(wsrc.c_str(), wdst.c_str(), nullptr))
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
}
int
FileSystem::GetHardlinkCount(const FileSpec &file_spec)
{
- HANDLE file_handle = ::CreateFile(file_spec.GetCString(),
+ std::wstring path;
+ if (!llvm::ConvertUTF8toWide(file_spec.GetCString(), path))
+ return -1;
+
+ HANDLE file_handle = ::CreateFileW(path.c_str(),
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ,
nullptr,
@@ -152,15 +172,21 @@
FileSystem::Symlink(const FileSpec &src, const FileSpec &dst)
{
Error error;
- DWORD attrib = ::GetFileAttributes(dst.GetCString());
+ std::wstring wsrc, wdst;
+ if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc) ||
+ !llvm::ConvertUTF8toWide(dst.GetCString(), wdst))
+ error.SetErrorString(PATH_CONVERSION_ERROR);
+ if (error.Fail())
+ return error;
+ DWORD attrib = ::GetFileAttributesW(wdst.c_str());
if (attrib == INVALID_FILE_ATTRIBUTES)
{
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
}
bool is_directory = !!(attrib & FILE_ATTRIBUTE_DIRECTORY);
DWORD flag = is_directory ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0;
- BOOL result = ::CreateSymbolicLink(src.GetCString(), dst.GetCString(), flag);
+ BOOL result = ::CreateSymbolicLinkW(wsrc.c_str(), wdst.c_str(), flag);
if (!result)
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
@@ -170,7 +196,13 @@
FileSystem::Unlink(const FileSpec &file_spec)
{
Error error;
- BOOL result = ::DeleteFile(file_spec.GetCString());
+ std::wstring path;
+ if (!llvm::ConvertUTF8toWide(file_spec.GetCString(), path))
+ {
+ error.SetErrorString(PATH_CONVERSION_ERROR);
+ return error;
+ }
+ BOOL result = ::DeleteFileW(path.c_str());
if (!result)
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
@@ -180,23 +212,33 @@
FileSystem::Readlink(const FileSpec &src, FileSpec &dst)
{
Error error;
- HANDLE h = ::CreateFile(src.GetCString(), GENERIC_READ,
+ std::wstring wsrc;
+ if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc))
+ {
+ error.SetErrorString(PATH_CONVERSION_ERROR);
+ return error;
+ }
+
+ HANDLE h = ::CreateFileW(wsrc.c_str(), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_OPEN_REPARSE_POINT, NULL);
if (h == INVALID_HANDLE_VALUE)
{
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
}
- char buf[PATH_MAX];
+ std::vector<wchar_t> buf(PATH_MAX + 1);
// Subtract 1 from the path length since this function does not add a null terminator.
- DWORD result = ::GetFinalPathNameByHandle(h, buf, sizeof(buf) - 1,
+ DWORD result = ::GetFinalPathNameByHandleW(h, buf.data(), buf.size() - 1,
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+ std::string path;
if (result == 0)
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
+ else if (!llvm::convertWideToUTF8(buf.data(), path))
+ error.SetErrorString(PATH_CONVERSION_ERROR);
else
- dst.SetFile(buf, false);
+ dst.SetFile(path, false);
::CloseHandle(h);
return error;
@@ -219,3 +261,17 @@
return false;
}
+
+FILE*
+FileSystem::Fopen(const char *path, const char *mode)
+{
+ std::wstring wpath, wmode;
+ if (!llvm::ConvertUTF8toWide(path, wpath))
+ return nullptr;
+ if (!llvm::ConvertUTF8toWide(mode, wmode))
+ return nullptr;
+ FILE* file;
+ if (_wfopen_s(&file, wpath.c_str(), wmode.c_str()) != 0)
+ return nullptr;
+ return file;
+}
Index: /lldb/trunksource/Host/windows/ConnectionGenericFileWindows.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Host/windows/ConnectionGenericFileWindows.cpp
@@ -14,6 +14,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ConvertUTF.h"
using namespace lldb;
using namespace lldb_private;
@@ -138,7 +139,14 @@
// Open the file for overlapped access. If it does not exist, create it. We open it overlapped
// so that we can issue asynchronous reads and then use WaitForMultipleObjects to allow the read
// to be interrupted by an event object.
- m_file = ::CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
+ std::wstring wpath;
+ if (!llvm::ConvertUTF8toWide(path, wpath))
+ {
+ if (error_ptr)
+ error_ptr->SetError(1, eErrorTypeGeneric);
+ return eConnectionStatusError;
+ }
+ m_file = ::CreateFileW(wpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
if (m_file == INVALID_HANDLE_VALUE)
{
if (error_ptr)
Index: /lldb/trunksource/Host/posix/HostInfoPosix.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Host/posix/HostInfoPosix.cpp
@@ -242,3 +242,14 @@
return false;
#endif
}
+
+bool
+HostInfoPosix::GetEnvironmentVar(const std::string &var_name, std::string &var)
+{
+ if (const char *pvar = ::getenv(var_name.c_str()))
+ {
+ var = std::string(pvar);
+ return true;
+ }
+ return false;
+}
Index: /lldb/trunksource/Host/posix/FileSystem.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Host/posix/FileSystem.cpp
@@ -299,3 +299,9 @@
return false;
}
#endif
+
+FILE*
+FileSystem::Fopen(const char *path, const char *mode)
+{
+ return ::fopen(path, mode);
+}
Index: /lldb/trunksource/Host/common/FileSpec.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Host/common/FileSpec.cpp
@@ -17,7 +17,6 @@
#ifndef _MSC_VER
#include <libgen.h>
#endif
-#include <sys/stat.h>
#include <set>
#include <string.h>
#include <fstream>
@@ -40,6 +39,7 @@
#include "lldb/Utility/CleanUp.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
@@ -90,7 +90,29 @@
{
char resolved_path[PATH_MAX];
if (file_spec->GetPath (resolved_path, sizeof(resolved_path)))
+ {
+#ifdef _WIN32
+ std::wstring wresolved_path;
+ if (!llvm::ConvertUTF8toWide(resolved_path, wresolved_path))
+ return false;
+ int stat_result;
+#ifdef _USE_32BIT_TIME_T
+ struct _stat32 file_stats;
+ stat_result = ::_wstat32(wresolved_path.c_str(), &file_stats);
+#else
+ struct _stat64i32 file_stats;
+ stat_result = ::_wstat64i32(wresolved_path.c_str(), &file_stats);
+#endif
+ if (stat_result == 0)
+ {
+ static_assert(sizeof(struct stat) == sizeof(file_stats), "stat and _stat32/_stat64i32 must have the same layout");
+ *stats_ptr = *reinterpret_cast<struct stat *>(&file_stats);
+ }
+ return stat_result == 0;
+#else
return ::stat (resolved_path, stats_ptr) == 0;
+#endif
+ }
return false;
}
@@ -206,15 +228,10 @@
#endif // #ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
// Save a copy of the original path that's passed in
- llvm::SmallString<PATH_MAX> original_path(path.begin(), path.end());
+ llvm::SmallString<128> original_path(path.begin(), path.end());
llvm::sys::fs::make_absolute(path);
-
-
- path.push_back(0); // Be sure we have a nul terminated string
- path.pop_back();
- struct stat file_stats;
- if (::stat (path.data(), &file_stats) != 0)
+ if (!llvm::sys::fs::exists(path))
{
path.clear();
path.append(original_path.begin(), original_path.end());
@@ -815,7 +832,10 @@
return false;
#ifdef _WIN32
- auto attrs = ::GetFileAttributes (resolved_path);
+ std::wstring wpath;
+ if (!llvm::ConvertUTF8toWide (resolved_path, wpath))
+ return false;
+ auto attrs = ::GetFileAttributesW (wpath.c_str());
if (attrs == INVALID_FILE_ATTRIBUTES)
return false;
@@ -1114,12 +1134,18 @@
{
if (dir_path && dir_path[0])
{
-#if _WIN32
+#ifdef _WIN32
std::string szDir(dir_path);
szDir += "\\*";
- WIN32_FIND_DATA ffd;
- HANDLE hFind = FindFirstFile(szDir.c_str(), &ffd);
+ std::wstring wszDir;
+ if (!llvm::ConvertUTF8toWide(szDir, wszDir))
+ {
+ return eEnumerateDirectoryResultNext;
+ }
+
+ WIN32_FIND_DATAW ffd;
+ HANDLE hFind = FindFirstFileW(wszDir.c_str(), &ffd);
if (hFind == INVALID_HANDLE_VALUE)
{
@@ -1131,12 +1157,12 @@
FileSpec::FileType file_type = eFileTypeUnknown;
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
- size_t len = strlen(ffd.cFileName);
+ size_t len = wcslen(ffd.cFileName);
- if (len == 1 && ffd.cFileName[0] == '.')
+ if (len == 1 && ffd.cFileName[0] == L'.')
continue;
- if (len == 2 && ffd.cFileName[0] == '.' && ffd.cFileName[1] == '.')
+ if (len == 2 && ffd.cFileName[0] == L'.' && ffd.cFileName[1] == L'.')
continue;
file_type = eFileTypeDirectory;
@@ -1150,12 +1176,18 @@
file_type = eFileTypeRegular;
}
- char child_path[MAX_PATH];
- const int child_path_len = ::snprintf (child_path, sizeof(child_path), "%s\\%s", dir_path, ffd.cFileName);
- if (child_path_len < (int)(sizeof(child_path) - 1))
+ std::string fileName;
+ if (!llvm::convertWideToUTF8(ffd.cFileName, fileName))
+ {
+ continue;
+ }
+
+ std::vector<char> child_path(PATH_MAX);
+ const int child_path_len = ::snprintf (child_path.data(), child_path.size(), "%s\\%s", dir_path, fileName.c_str());
+ if (child_path_len < (int)(child_path.size() - 1))
{
// Don't resolve the file type or path
- FileSpec child_path_spec (child_path, false);
+ FileSpec child_path_spec (child_path.data(), false);
EnumerateDirectoryResult result = callback (file_type, child_path_spec);
@@ -1168,7 +1200,7 @@
break;
case eEnumerateDirectoryResultEnter: // Recurse into the current entry if it is a directory or symlink, or next if not
- if (FileSpec::ForEachItemInDirectory(child_path, callback) == eEnumerateDirectoryResultQuit)
+ if (FileSpec::ForEachItemInDirectory(child_path.data(), callback) == eEnumerateDirectoryResultQuit)
{
// The subdirectory returned Quit, which means to
// stop all directory enumerations at all levels.
@@ -1185,7 +1217,7 @@
return eEnumerateDirectoryResultQuit;
}
}
- } while (FindNextFile(hFind, &ffd) != 0);
+ } while (FindNextFileW(hFind, &ffd) != 0);
FindClose(hFind);
#else
Index: /lldb/trunksource/Host/common/File.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Host/common/File.cpp
@@ -22,6 +22,7 @@
#include <sys/ioctl.h>
#endif
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Process.h" // for llvm::sys::Process::FileDescriptorHasColors()
#include "lldb/Core/DataBufferHeap.h"
@@ -267,7 +268,18 @@
do
{
+#ifdef _WIN32
+ std::wstring wpath;
+ if (!llvm::ConvertUTF8toWide(path, wpath))
+ {
+ m_descriptor = -1;
+ error.SetErrorString("Error converting path to UTF-16");
+ return error;
+ }
+ ::_wsopen_s(&m_descriptor, wpath.c_str(), oflag, _SH_DENYNO, mode);
+#else
m_descriptor = ::open(path, oflag, mode);
+#endif
} while (m_descriptor < 0 && errno == EINTR);
if (!DescriptorIsValid())
@@ -286,8 +298,21 @@
{
if (file_spec)
{
+ int stat_result;
+#ifdef _WIN32
+ std::wstring wpath;
+ if (!llvm::ConvertUTF8toWide(file_spec.GetCString(), wpath))
+ {
+ error.SetErrorString("Error converting path to UTF-16");
+ return 0;
+ }
+ struct _stat32 file_stats;
+ stat_result = ::_wstat32(wpath.c_str(), &file_stats);
+#else
struct stat file_stats;
- if (::stat(file_spec.GetCString(), &file_stats) == -1)
+ stat_result = ::stat(file_spec.GetCString(), &file_stats);
+#endif
+ if (stat_result == -1)
error.SetErrorToErrno();
else
{
Index: /lldb/trunksource/Core/Disassembler.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Core/Disassembler.cpp
@@ -27,6 +27,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Timer.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Interpreter/OptionValue.h"
#include "lldb/Interpreter/OptionValueArray.h"
#include "lldb/Interpreter/OptionValueDictionary.h"
@@ -850,8 +851,7 @@
out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
return false;
}
-
- FILE *test_file = fopen (file_name, "r");
+ FILE *test_file = FileSystem::Fopen ( file_name, "r");
if (!test_file)
{
out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
Index: /lldb/trunksource/Core/ConnectionSharedMemory.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Core/ConnectionSharedMemory.cpp
@@ -32,6 +32,8 @@
#include "lldb/Core/Communication.h"
#include "lldb/Core/Log.h"
+#include "llvm/Support/ConvertUTF.h"
+
using namespace lldb;
using namespace lldb_private;
@@ -135,18 +137,22 @@
m_name.assign (name);
#ifdef _WIN32
- HANDLE handle;
- if (create) {
- handle = CreateFileMapping(
- INVALID_HANDLE_VALUE,
- nullptr,
- PAGE_READWRITE,
- llvm::Hi_32(size),
- llvm::Lo_32(size),
- name);
+ HANDLE handle = INVALID_HANDLE_VALUE;
+ std::wstring wname;
+ if (llvm::ConvertUTF8toWide(name, wname))
+ {
+ if (create) {
+ handle = CreateFileMappingW(
+ INVALID_HANDLE_VALUE,
+ NULL,
+ PAGE_READWRITE,
+ llvm::Hi_32(size),
+ llvm::Lo_32(size),
+ wname.c_str());
+ }
+ else
+ handle = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, wname.c_str());
}
- else
- handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, name);
m_fd = _open_osfhandle((intptr_t)handle, 0);
#else
Index: /lldb/trunksource/Commands/CommandCompletions.cpp
===================================================================
--- /dev/null
+++ /lldb/trunksource/Commands/CommandCompletions.cpp
@@ -19,6 +19,7 @@
// Project includes
#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Module.h"
@@ -31,6 +32,8 @@
#include "lldb/Target/Target.h"
#include "lldb/Utility/CleanUp.h"
+#include "llvm/ADT/SmallString.h"
+
using namespace lldb_private;
CommandCompletions::CommonCompletionElement
@@ -160,8 +163,7 @@
isa_directory = true;
else if (file_type == FileSpec::eFileTypeSymbolicLink)
{
- struct stat stat_buf;
- if ((stat(partial_name_copy, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode))
+ if (FileSpec(partial_name_copy, false).IsDirectory())
isa_directory = true;
}
Index: /lldb/trunkpackages/Python/lldbsuite/test/dotest.py
===================================================================
--- /dev/null
+++ /lldb/trunkpackages/Python/lldbsuite/test/dotest.py
@@ -659,7 +659,7 @@
print(" location of LLDB\'s site-packages folder.")
print(" 3) A different version of Python than that which was built against is exported in")
print(" the system\'s PATH environment variable, causing conflicts.")
- print(" 4) The executable '%s' could not be found. Please check " % lldbExecutable)
+ print(" 4) The executable '%s' could not be found. Please check " % lldbtest_config.lldbExec)
print(" that it exists and is executable.")
if lldbPythonDir:
Index: /lldb/trunkinclude/lldb/Host/windows/HostInfoWindows.h
===================================================================
--- /dev/null
+++ /lldb/trunkinclude/lldb/Host/windows/HostInfoWindows.h
@@ -47,6 +47,8 @@
static FileSpec
GetDefaultShell();
+ static bool GetEnvironmentVar(const std::string &var_name, std::string &var);
+
protected:
static bool ComputePythonDirectory(FileSpec &file_spec);
Index: /lldb/trunkinclude/lldb/Host/posix/HostInfoPosix.h
===================================================================
--- /dev/null
+++ /lldb/trunkinclude/lldb/Host/posix/HostInfoPosix.h
@@ -33,6 +33,8 @@
static FileSpec GetDefaultShell();
+ static bool GetEnvironmentVar(const std::string &var_name, std::string &var);
+
protected:
static bool ComputeSupportExeDirectory(FileSpec &file_spec);
static bool ComputeHeaderDirectory(FileSpec &file_spec);
Index: /lldb/trunkinclude/lldb/Host/FileSystem.h
===================================================================
--- /dev/null
+++ /lldb/trunkinclude/lldb/Host/FileSystem.h
@@ -11,6 +11,8 @@
#define liblldb_Host_FileSystem_h
#include <stdint.h>
+#include <stdio.h>
+#include <sys/stat.h>
#include "lldb/lldb-types.h"
@@ -23,6 +25,7 @@
{
public:
static const char *DEV_NULL;
+ static const char *PATH_CONVERSION_ERROR;
static FileSpec::PathSyntax GetNativePathSyntax();
@@ -59,6 +62,10 @@
/// Return \b true if \a spec is on a locally mounted file system, \b false otherwise.
static bool IsLocal(const FileSpec &spec);
+
+ /// Wraps ::fopen in a platform-independent way. Once opened, FILEs can be
+ /// manipulated and closed with the normal ::fread, ::fclose, etc. functions.
+ static FILE* Fopen(const char *path, const char *mode);
};
}
Index: /lldb/trunkcmake/modules/LLDBConfig.cmake
===================================================================
--- /dev/null
+++ /lldb/trunkcmake/modules/LLDBConfig.cmake
@@ -245,6 +245,11 @@
)
endif()
+# Use the Unicode (UTF-16) APIs by default on Win32
+if (CMAKE_SYSTEM_NAME MATCHES "Windows")
+ add_definitions( /D _UNICODE /D UNICODE )
+endif()
+
set(LLDB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(LLDB_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits