diff options
Diffstat (limited to 'src/main')
-rw-r--r-- | src/main/cpp/BUILD | 10 | ||||
-rw-r--r-- | src/main/cpp/blaze.cc | 19 | ||||
-rw-r--r-- | src/main/cpp/blaze_util.cc | 32 | ||||
-rw-r--r-- | src/main/cpp/blaze_util.h | 2 | ||||
-rw-r--r-- | src/main/cpp/blaze_util_mingw.cc | 94 | ||||
-rw-r--r-- | src/main/cpp/blaze_util_platform.h | 14 | ||||
-rw-r--r-- | src/main/cpp/blaze_util_posix.cc | 63 | ||||
-rw-r--r-- | src/main/cpp/option_processor.cc | 5 |
8 files changed, 194 insertions, 45 deletions
diff --git a/src/main/cpp/BUILD b/src/main/cpp/BUILD index c1f472b4fd..3a1239f088 100644 --- a/src/main/cpp/BUILD +++ b/src/main/cpp/BUILD @@ -4,8 +4,14 @@ filegroup( name = "blaze_util_os", srcs = select({ - "//src:darwin": ["blaze_util_darwin.cc"], - "//conditions:default": ["blaze_util_linux.cc"], + "//src:darwin": [ + "blaze_util_darwin.cc", + "blaze_util_posix.cc", + ], + "//conditions:default": [ + "blaze_util_linux.cc", + "blaze_util_posix.cc", + ], }), ) diff --git a/src/main/cpp/blaze.cc b/src/main/cpp/blaze.cc index 4c1b08d041..ffcbf00447 100644 --- a/src/main/cpp/blaze.cc +++ b/src/main/cpp/blaze.cc @@ -276,11 +276,11 @@ static vector<string> GetArgumentArray() { for (const auto& it : globals->extracted_binaries) { if (IsSharedLibrary(it)) { if (!first) { - java_library_path += ":"; + java_library_path += blaze::ListSeparator(); } first = false; - java_library_path += blaze_util::JoinPath(real_install_dir, - blaze_util::Dirname(it)); + java_library_path += blaze::ConvertPath( + blaze_util::JoinPath(real_install_dir, blaze_util::Dirname(it))); } } result.push_back(java_library_path); @@ -299,8 +299,8 @@ static vector<string> GetArgumentArray() { result.insert(result.end(), user_options.begin(), user_options.end()); result.push_back("-jar"); - result.push_back(blaze_util::JoinPath(real_install_dir, - globals->extracted_binaries[0])); + result.push_back(blaze::ConvertPath( + blaze_util::JoinPath(real_install_dir, globals->extracted_binaries[0]))); if (!globals->options.batch) { result.push_back("--max_idle_secs"); @@ -310,9 +310,12 @@ static vector<string> GetArgumentArray() { // the code expects it to be at args[0] if it's been set. result.push_back("--batch"); } - result.push_back("--install_base=" + globals->options.install_base); - result.push_back("--output_base=" + globals->options.output_base); - result.push_back("--workspace_directory=" + globals->workspace); + result.push_back("--install_base=" + + blaze::ConvertPath(globals->options.install_base)); + result.push_back("--output_base=" + + blaze::ConvertPath(globals->options.output_base)); + result.push_back("--workspace_directory=" + + blaze::ConvertPath(globals->workspace)); if (!globals->options.skyframe.empty()) { result.push_back("--skyframe=" + globals->options.skyframe); } diff --git a/src/main/cpp/blaze_util.cc b/src/main/cpp/blaze_util.cc index ae84d75d59..a6d96decf6 100644 --- a/src/main/cpp/blaze_util.cc +++ b/src/main/cpp/blaze_util.cc @@ -32,6 +32,7 @@ #include <sstream> +#include "src/main/cpp/blaze_util_platform.h" #include "src/main/cpp/util/errors.h" #include "src/main/cpp/util/exit_code.h" #include "src/main/cpp/util/file.h" @@ -243,37 +244,6 @@ int GetTerminalColumns() { return 80; // default if not a terminal. } -// Replace the current process with the given program in the given working -// directory, using the given argument vector. -// This function does not return on success. -void ExecuteProgram(const string& exe, const vector<string>& args_vector) { - if (VerboseLogging()) { - string dbg; - for (const auto& s : args_vector) { - dbg.append(s); - dbg.append(" "); - } - - char cwd[PATH_MAX] = {}; - if (getcwd(cwd, sizeof(cwd)) == NULL) { - pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "getcwd() failed"); - } - - fprintf(stderr, "Invoking binary %s in %s:\n %s\n", - exe.c_str(), cwd, dbg.c_str()); - } - - // Copy to a char* array for execv: - int n = args_vector.size(); - const char **argv = new const char *[n + 1]; - for (int i = 0; i < n; ++i) { - argv[i] = args_vector[i].c_str(); - } - argv[n] = NULL; - - execv(exe.c_str(), const_cast<char**>(argv)); -} - const char* GetUnaryOption(const char *arg, const char *next_arg, const char *key) { diff --git a/src/main/cpp/blaze_util.h b/src/main/cpp/blaze_util.h index 4cf6dc98b5..a43deea75d 100644 --- a/src/main/cpp/blaze_util.h +++ b/src/main/cpp/blaze_util.h @@ -66,8 +66,6 @@ int GetTerminalColumns(); void AddJVMSpecificArguments(const string &host_javabase, std::vector<string> *result); -void ExecuteProgram(const string &exe, const std::vector<string> &args_vector); - // If 'arg' matches 'key=value', returns address of 'value'. // If it matches 'key' alone, returns address of next_arg. // Returns NULL otherwise. diff --git a/src/main/cpp/blaze_util_mingw.cc b/src/main/cpp/blaze_util_mingw.cc index 040a6bd636..7ecfc49f5f 100644 --- a/src/main/cpp/blaze_util_mingw.cc +++ b/src/main/cpp/blaze_util_mingw.cc @@ -17,8 +17,11 @@ #include <string.h> // strerror #include <sys/socket.h> #include <sys/statfs.h> +#include <sys/cygwin.h> #include <unistd.h> +#include <windows.h> + #include <cstdlib> #include <cstdio> @@ -107,4 +110,95 @@ string GetDefaultHostJavabase() { return javahome; } +// Replace the current process with the given program in the given working +// directory, using the given argument vector. +// This function does not return on success. +void ExecuteProgram(const string& exe, const vector<string>& args_vector) { + if (VerboseLogging()) { + string dbg; + for (const auto& s : args_vector) { + dbg.append(s); + dbg.append(" "); + } + + char cwd[PATH_MAX] = {}; + if (getcwd(cwd, sizeof(cwd)) == NULL) { + pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "getcwd() failed"); + } + + fprintf(stderr, "Invoking binary %s in %s:\n %s\n", exe.c_str(), cwd, + dbg.c_str()); + } + + // Build full command line. + string cmdline; + bool first = true; + for (const auto& s : args_vector) { + if (first) { + first = false; + // Skip first argument, instead use quoted executable name with ".exe" + // suffix. + cmdline.append("\""); + cmdline.append(exe); + cmdline.append(".exe"); + cmdline.append("\""); + continue; + } else { + cmdline.append(" "); + } + cmdline.append(s); + } + + // Copy command line into a mutable buffer. + // CreateProcess is allowed to mutate its command line argument. + // Max command line length is per CreateProcess documentation + // (https://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx) + static const int kMaxCmdLineLength = 32768; + char actual_line[kMaxCmdLineLength]; + if (cmdline.length() >= kMaxCmdLineLength) { + pdie(255, "Command line too long: %s", cmdline.c_str()); + } + strncpy(actual_line, cmdline.c_str(), kMaxCmdLineLength); + // Add trailing '\0' to be sure. + actual_line[kMaxCmdLineLength - 1] = '\0'; + + // Execute program. + STARTUPINFO startupinfo = {0}; + PROCESS_INFORMATION pi = {0}; + + bool success = CreateProcess( + nullptr, // _In_opt_ LPCTSTR lpApplicationName, + actual_line, // _Inout_opt_ LPTSTR lpCommandLine, + nullptr, // _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + nullptr, // _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + true, // _In_ BOOL bInheritHandles, + 0, // _In_ DWORD dwCreationFlags, + nullptr, // _In_opt_ LPVOID lpEnvironment, + nullptr, // _In_opt_ LPCTSTR lpCurrentDirectory, + &startupinfo, // _In_ LPSTARTUPINFO lpStartupInfo, + &pi); // _Out_ LPPROCESS_INFORMATION lpProcessInformation + + if (!success) { + pdie(255, "Error %u executing: %s\n", GetLastError(), actual_line); + } + WaitForSingleObject(pi.hProcess, INFINITE); + DWORD exit_code; + GetExitCodeProcess(pi.hProcess, &exit_code); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + + // Emulate execv. + exit(exit_code); +} + +string ListSeparator() { return ";"; } + +string ConvertPath(const string& path) { + char* wpath = static_cast<char*>(cygwin_create_path( + CCP_POSIX_TO_WIN_A, static_cast<const void*>(path.c_str()))); + string result(wpath); + free(wpath); + return result; +} + } // namespace blaze diff --git a/src/main/cpp/blaze_util_platform.h b/src/main/cpp/blaze_util_platform.h index 014254e276..a2ba4eda57 100644 --- a/src/main/cpp/blaze_util_platform.h +++ b/src/main/cpp/blaze_util_platform.h @@ -54,6 +54,20 @@ bool IsSharedLibrary(const std::string& filename); // (must be an absolute directory). std::string GetDefaultHostJavabase(); +// Replace the current process with the given program in the given working +// directory, using the given argument vector. +// This function does not return on success. +void ExecuteProgram(const string& exe, const std::vector<string>& args_vector); + +// Convert a path from Bazel internal form to underlying OS form. +// On Unixes this is an identity operation. +// On Windows, Bazel internal from is cygwin path, and underlying OS form +// is Windows path. +std::string ConvertPath(const std::string& path); + +// Return a string used to separate paths in a list. +std::string ListSeparator(); + } // namespace blaze #endif // BAZEL_SRC_MAIN_CPP_BLAZE_UTIL_PLATFORM_H_ diff --git a/src/main/cpp/blaze_util_posix.cc b/src/main/cpp/blaze_util_posix.cc new file mode 100644 index 0000000000..ec6ea0ad46 --- /dev/null +++ b/src/main/cpp/blaze_util_posix.cc @@ -0,0 +1,63 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <limits.h> +#include <sys/types.h> +#include <unistd.h> + +#include "src/main/cpp/blaze_util.h" +#include "src/main/cpp/blaze_util_platform.h" +#include "src/main/cpp/util/errors.h" +#include "src/main/cpp/util/exit_code.h" + +namespace blaze { + +using blaze_util::die; +using blaze_util::pdie; + +using std::string; +using std::vector; + +void ExecuteProgram(const string &exe, const vector<string> &args_vector) { + if (VerboseLogging()) { + string dbg; + for (const auto &s : args_vector) { + dbg.append(s); + dbg.append(" "); + } + + char cwd[PATH_MAX] = {}; + if (getcwd(cwd, sizeof(cwd)) == NULL) { + pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "getcwd() failed"); + } + + fprintf(stderr, "Invoking binary %s in %s:\n %s\n", exe.c_str(), cwd, + dbg.c_str()); + } + + // Copy to a char* array for execv: + int n = args_vector.size(); + const char **argv = new const char *[n + 1]; + for (int i = 0; i < n; ++i) { + argv[i] = args_vector[i].c_str(); + } + argv[n] = NULL; + + execv(exe.c_str(), const_cast<char **>(argv)); +} + +std::string ConvertPath(const std::string &path) { return path; } + +std::string ListSeparator() { return ":"; } +} // namespace blaze. diff --git a/src/main/cpp/option_processor.cc b/src/main/cpp/option_processor.cc index 5f4fd2aa13..a137eb3943 100644 --- a/src/main/cpp/option_processor.cc +++ b/src/main/cpp/option_processor.cc @@ -432,7 +432,8 @@ void OptionProcessor::AddRcfileArgsAndOptions(bool batch, const string& cwd) { // Push the options mapping .blazerc numbers to filenames. for (int i_blazerc = 0; i_blazerc < blazercs_.size(); i_blazerc++) { const RcFile* blazerc = blazercs_[i_blazerc]; - command_arguments_.push_back("--rc_source=" + blazerc->Filename()); + command_arguments_.push_back("--rc_source=" + + blaze::ConvertPath(blazerc->Filename())); } // Push the option defaults @@ -465,7 +466,7 @@ void OptionProcessor::AddRcfileArgsAndOptions(bool batch, const string& cwd) { command_arguments_.push_back("--client_env=" + string(*env)); } } - command_arguments_.push_back("--client_cwd=" + cwd); + command_arguments_.push_back("--client_cwd=" + blaze::ConvertPath(cwd)); const char *emacs = getenv("EMACS"); if (emacs != NULL && strcmp(emacs, "t") == 0) { |