aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools/launcher/launcher.cc
diff options
context:
space:
mode:
authorGravatar Yun Peng <pcloudy@google.com>2018-06-25 05:35:50 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-06-25 05:36:55 -0700
commit40f5a773e97d0e389838becd3fe0a8ab43853999 (patch)
tree2c2aec321caa559b43787281fd097a7545eacc28 /src/tools/launcher/launcher.cc
parentd753745d58fc45fcb50623073829644812083da0 (diff)
Windows: Native launcher now works with unicode.
The native launcher can now launch Java and Bash binary in directory with non-English characters. Unfortunately, python doesn't support running python zip file under directory with non-English characters. eg. python ./??/bin.zip will still fail. See https://github.com/bazelbuild/bazel/issues/4473 Change-Id: I77fe9cdaabffc2e0d25c7097da5c0c9333a9c4a3 PiperOrigin-RevId: 201939391
Diffstat (limited to 'src/tools/launcher/launcher.cc')
-rw-r--r--src/tools/launcher/launcher.cc132
1 files changed, 70 insertions, 62 deletions
diff --git a/src/tools/launcher/launcher.cc b/src/tools/launcher/launcher.cc
index 9bcc3642c2..b663c2cc77 100644
--- a/src/tools/launcher/launcher.cc
+++ b/src/tools/launcher/launcher.cc
@@ -21,6 +21,7 @@
#include <vector>
#include "src/main/cpp/util/path_platform.h"
+#include "src/main/cpp/util/strings.h"
#include "src/tools/launcher/launcher.h"
#include "src/tools/launcher/util/data_parser.h"
#include "src/tools/launcher/util/launcher_util.h"
@@ -29,25 +30,26 @@ namespace bazel {
namespace launcher {
using std::ifstream;
-using std::ostringstream;
using std::string;
using std::unordered_map;
using std::vector;
+using std::wostringstream;
+using std::wstring;
-static std::string GetRunfilesDir(const char* argv0) {
- string runfiles_dir;
+static wstring GetRunfilesDir(const wchar_t* argv0) {
+ wstring runfiles_dir;
// If RUNFILES_DIR is already set (probably we are either in a test or in a
// data dependency) then use it.
- if (GetEnv("RUNFILES_DIR", &runfiles_dir)) {
+ if (GetEnv(L"RUNFILES_DIR", &runfiles_dir)) {
return runfiles_dir;
}
// Otherwise this is probably a top-level non-test binary (e.g. a genrule
// tool) and should look for its runfiles beside the executable.
- return GetBinaryPathWithExtension(argv0) + ".runfiles";
+ return GetBinaryPathWithExtension(argv0) + L".runfiles";
}
BinaryLauncherBase::BinaryLauncherBase(
- const LaunchDataParser::LaunchInfo& _launch_info, int argc, char* argv[])
+ const LaunchDataParser::LaunchInfo& _launch_info, int argc, wchar_t* argv[])
: launch_info(_launch_info),
manifest_file(FindManifestFile(argv[0])),
runfiles_dir(GetRunfilesDir(argv[0])),
@@ -58,22 +60,22 @@ BinaryLauncherBase::BinaryLauncherBase(
// Prefer to use the runfiles manifest, if it exists, but otherwise the
// runfiles directory will be used by default. On Windows, the manifest is
// used locally, and the runfiles directory is used remotely.
- if (manifest_file != "") {
+ if (!manifest_file.empty()) {
ParseManifestFile(&manifest_file_map, manifest_file);
}
}
-static bool FindManifestFileImpl(const char* argv0, string* result) {
+static bool FindManifestFileImpl(const wchar_t* argv0, wstring* result) {
// If this binary X runs as the data-dependency of some other binary Y, then
// X has no runfiles manifest/directory and should use Y's.
- if (GetEnv("RUNFILES_MANIFEST_FILE", result) &&
+ if (GetEnv(L"RUNFILES_MANIFEST_FILE", result) &&
DoesFilePathExist(result->c_str())) {
return true;
}
- string directory;
- if (GetEnv("RUNFILES_DIR", &directory)) {
- *result = directory + "/MANIFEST";
+ wstring directory;
+ if (GetEnv(L"RUNFILES_DIR", &directory)) {
+ *result = directory + L"/MANIFEST";
if (DoesFilePathExist(result->c_str())) {
return true;
}
@@ -82,13 +84,13 @@ static bool FindManifestFileImpl(const char* argv0, string* result) {
// If this binary X runs by itself (not as a data-dependency of another
// binary), then look for the manifest in a runfiles directory next to the
// main binary, then look for it (the manifest) next to the main binary.
- directory = GetBinaryPathWithExtension(argv0) + ".runfiles";
- *result = directory + "/MANIFEST";
+ directory = GetBinaryPathWithExtension(argv0) + L".runfiles";
+ *result = directory + L"/MANIFEST";
if (DoesFilePathExist(result->c_str())) {
return true;
}
- *result = directory + "_manifest";
+ *result = directory + L"_manifest";
if (DoesFilePathExist(result->c_str())) {
return true;
}
@@ -96,10 +98,10 @@ static bool FindManifestFileImpl(const char* argv0, string* result) {
return false;
}
-string BinaryLauncherBase::FindManifestFile(const char* argv0) {
- string manifest_file;
+wstring BinaryLauncherBase::FindManifestFile(const wchar_t* argv0) {
+ wstring manifest_file;
if (!FindManifestFileImpl(argv0, &manifest_file)) {
- return "";
+ return L"";
}
// The path will be set as the RUNFILES_MANIFEST_FILE envvar and used by the
// shell script, so let's convert backslashes to forward slashes.
@@ -107,35 +109,36 @@ string BinaryLauncherBase::FindManifestFile(const char* argv0) {
return manifest_file;
}
-string BinaryLauncherBase::GetRunfilesPath() const {
- string runfiles_path =
- GetBinaryPathWithExtension(this->commandline_arguments[0]) + ".runfiles";
- std::replace(runfiles_path.begin(), runfiles_path.end(), '/', '\\');
+wstring BinaryLauncherBase::GetRunfilesPath() const {
+ wstring runfiles_path =
+ GetBinaryPathWithExtension(this->commandline_arguments[0]) + L".runfiles";
+ std::replace(runfiles_path.begin(), runfiles_path.end(), L'/', L'\\');
return runfiles_path;
}
void BinaryLauncherBase::ParseManifestFile(ManifestFileMap* manifest_file_map,
- const string& manifest_path) {
+ const wstring& manifest_path) {
ifstream manifest_file(AsAbsoluteWindowsPath(manifest_path.c_str()).c_str());
if (!manifest_file) {
- die("Couldn't open MANIFEST file: %s", manifest_path.c_str());
+ die(L"Couldn't open MANIFEST file: %s", manifest_path.c_str());
}
string line;
while (getline(manifest_file, line)) {
size_t space_pos = line.find_first_of(' ');
if (space_pos == string::npos) {
- die("Wrong MANIFEST format at line: %s", line.c_str());
+ die(L"Wrong MANIFEST format at line: %s", line.c_str());
}
- string key = line.substr(0, space_pos);
- string value = line.substr(space_pos + 1);
+ wstring wline = blaze_util::CstringToWstring(line);
+ wstring key = wline.substr(0, space_pos);
+ wstring value = wline.substr(space_pos + 1);
manifest_file_map->insert(make_pair(key, value));
}
}
-string BinaryLauncherBase::Rlocation(const string& path,
- bool need_workspace_name) const {
+wstring BinaryLauncherBase::Rlocation(const wstring& path,
+ bool need_workspace_name) const {
// If the manifest file map is empty, then we're using the runfiles directory
// instead.
if (manifest_file_map.empty()) {
@@ -143,106 +146,111 @@ string BinaryLauncherBase::Rlocation(const string& path,
return path;
}
- string query_path = runfiles_dir;
+ wstring query_path = runfiles_dir;
if (need_workspace_name) {
- query_path += "/" + this->workspace_name;
+ query_path += L"/" + this->workspace_name;
}
- query_path += "/" + path;
+ query_path += L"/" + path;
return query_path;
}
- string query_path = path;
+ wstring query_path = path;
if (need_workspace_name) {
- query_path = this->workspace_name + "/" + path;
+ query_path = this->workspace_name + L"/" + path;
}
auto entry = manifest_file_map.find(query_path);
if (entry == manifest_file_map.end()) {
- die("Rlocation failed on %s, path doesn't exist in MANIFEST file",
+ die(L"Rlocation failed on %s, path doesn't exist in MANIFEST file",
query_path.c_str());
}
return entry->second;
}
-string BinaryLauncherBase::GetLaunchInfoByKey(const string& key) {
+wstring BinaryLauncherBase::Rlocation(const string& path,
+ bool need_workspace_name) const {
+ return this->Rlocation(blaze_util::CstringToWstring(path),
+ need_workspace_name);
+}
+
+wstring BinaryLauncherBase::GetLaunchInfoByKey(const string& key) {
auto item = launch_info.find(key);
if (item == launch_info.end()) {
- die("Cannot find key \"%s\" from launch data.\n", key.c_str());
+ die(L"Cannot find key \"%hs\" from launch data.\n", key.c_str());
}
return item->second;
}
-const vector<string>& BinaryLauncherBase::GetCommandlineArguments() const {
+const vector<wstring>& BinaryLauncherBase::GetCommandlineArguments() const {
return this->commandline_arguments;
}
void BinaryLauncherBase::CreateCommandLine(
- CmdLine* result, const string& executable,
- const vector<string>& arguments) const {
- ostringstream cmdline;
- cmdline << '\"' << executable << '\"';
+ CmdLine* result, const wstring& executable,
+ const vector<wstring>& arguments) const {
+ wostringstream cmdline;
+ cmdline << L'\"' << executable << L'\"';
for (const auto& s : arguments) {
- cmdline << ' ' << s;
+ cmdline << L' ' << s;
}
- string cmdline_str = cmdline.str();
+ wstring cmdline_str = cmdline.str();
if (cmdline_str.size() >= MAX_CMDLINE_LENGTH) {
- die("Command line too long: %s", cmdline_str.c_str());
+ die(L"Command line too long: %s", cmdline_str.c_str());
}
// Copy command line into a mutable buffer.
// CreateProcess is allowed to mutate its command line argument.
- strncpy(result->cmdline, cmdline_str.c_str(), MAX_CMDLINE_LENGTH - 1);
+ wcsncpy(result->cmdline, cmdline_str.c_str(), MAX_CMDLINE_LENGTH - 1);
result->cmdline[MAX_CMDLINE_LENGTH - 1] = 0;
}
bool BinaryLauncherBase::PrintLauncherCommandLine(
- const string& executable, const vector<string>& arguments) const {
+ const wstring& executable, const vector<wstring>& arguments) const {
bool has_print_cmd_flag = false;
for (const auto& arg : arguments) {
- has_print_cmd_flag |= (arg == "--print_launcher_command");
+ has_print_cmd_flag |= (arg == L"--print_launcher_command");
}
if (has_print_cmd_flag) {
- printf("%s\n", executable.c_str());
+ wprintf(L"%s\n", executable.c_str());
for (const auto& arg : arguments) {
- printf("%s\n", arg.c_str());
+ wprintf(L"%s\n", arg.c_str());
}
}
return has_print_cmd_flag;
}
-ExitCode BinaryLauncherBase::LaunchProcess(const string& executable,
- const vector<string>& arguments,
+ExitCode BinaryLauncherBase::LaunchProcess(const wstring& executable,
+ const vector<wstring>& arguments,
bool suppressOutput) const {
if (PrintLauncherCommandLine(executable, arguments)) {
return 0;
}
- if (manifest_file != "") {
- SetEnv("RUNFILES_MANIFEST_ONLY", "1");
- SetEnv("RUNFILES_MANIFEST_FILE", manifest_file);
+ if (!manifest_file.empty()) {
+ SetEnv(L"RUNFILES_MANIFEST_ONLY", L"1");
+ SetEnv(L"RUNFILES_MANIFEST_FILE", manifest_file);
} else {
- SetEnv("RUNFILES_DIR", runfiles_dir);
+ SetEnv(L"RUNFILES_DIR", runfiles_dir);
}
CmdLine cmdline;
CreateCommandLine(&cmdline, executable, arguments);
PROCESS_INFORMATION processInfo = {0};
- STARTUPINFOA startupInfo = {0};
+ STARTUPINFOW startupInfo = {0};
startupInfo.cb = sizeof(startupInfo);
- BOOL ok = CreateProcessA(
+ BOOL ok = CreateProcessW(
/* lpApplicationName */ NULL,
/* lpCommandLine */ cmdline.cmdline,
/* lpProcessAttributes */ NULL,
/* lpThreadAttributes */ NULL,
/* bInheritHandles */ FALSE,
/* dwCreationFlags */
- suppressOutput ? CREATE_NO_WINDOW // no console window => no output
- : 0,
+ suppressOutput ? CREATE_NO_WINDOW // no console window => no output
+ : 0,
/* lpEnvironment */ NULL,
/* lpCurrentDirectory */ NULL,
/* lpStartupInfo */ &startupInfo,
/* lpProcessInformation */ &processInfo);
if (!ok) {
- PrintError("Cannot launch process: %s\nReason: %s",
- cmdline.cmdline,
+ PrintError(L"Cannot launch process: %s\nReason: %hs", cmdline.cmdline,
GetLastErrorString().c_str());
return GetLastError();
}