diff options
| -rw-r--r-- | compiler/utils/assembler_test_base.h | 1 | ||||
| -rw-r--r-- | dexdump/dexdump_test.cc | 1 | ||||
| -rw-r--r-- | dexlayout/dexlayout_test.cc | 1 | ||||
| -rw-r--r-- | dexlist/dexlist_test.cc | 1 | ||||
| -rw-r--r-- | imgdiag/imgdiag_test.cc | 1 | ||||
| -rw-r--r-- | oatdump/oatdump_test.cc | 1 | ||||
| -rw-r--r-- | profman/profile_assistant_test.cc | 1 | ||||
| -rw-r--r-- | runtime/Android.bp | 1 | ||||
| -rw-r--r-- | runtime/dex2oat_environment_test.h | 1 | ||||
| -rw-r--r-- | runtime/exec_utils.cc | 102 | ||||
| -rw-r--r-- | runtime/exec_utils.h | 34 | ||||
| -rw-r--r-- | runtime/gc/space/image_space.cc | 1 | ||||
| -rw-r--r-- | runtime/oat_file_assistant.cc | 1 | ||||
| -rw-r--r-- | runtime/utils.cc | 68 | ||||
| -rw-r--r-- | runtime/utils.h | 7 | ||||
| -rw-r--r-- | runtime/utils_test.cc | 1 |
16 files changed, 148 insertions, 75 deletions
diff --git a/compiler/utils/assembler_test_base.h b/compiler/utils/assembler_test_base.h index e7edf96722..d76cb1c1df 100644 --- a/compiler/utils/assembler_test_base.h +++ b/compiler/utils/assembler_test_base.h @@ -26,6 +26,7 @@ #include "android-base/strings.h" #include "common_runtime_test.h" // For ScratchFile +#include "exec_utils.h" #include "utils.h" namespace art { diff --git a/dexdump/dexdump_test.cc b/dexdump/dexdump_test.cc index 53dda6a995..640f387a80 100644 --- a/dexdump/dexdump_test.cc +++ b/dexdump/dexdump_test.cc @@ -23,6 +23,7 @@ #include "common_runtime_test.h" #include "runtime/arch/instruction_set.h" +#include "runtime/exec_utils.h" #include "runtime/os.h" #include "runtime/utils.h" #include "utils.h" diff --git a/dexlayout/dexlayout_test.cc b/dexlayout/dexlayout_test.cc index 46a1c43548..da1e1d26dc 100644 --- a/dexlayout/dexlayout_test.cc +++ b/dexlayout/dexlayout_test.cc @@ -23,6 +23,7 @@ #include "base/unix_file/fd_file.h" #include "common_runtime_test.h" +#include "exec_utils.h" #include "utils.h" namespace art { diff --git a/dexlist/dexlist_test.cc b/dexlist/dexlist_test.cc index 13209427c9..173a456982 100644 --- a/dexlist/dexlist_test.cc +++ b/dexlist/dexlist_test.cc @@ -23,6 +23,7 @@ #include "common_runtime_test.h" #include "runtime/arch/instruction_set.h" +#include "runtime/exec_utils.h" #include "runtime/gc/heap.h" #include "runtime/gc/space/image_space.h" #include "runtime/os.h" diff --git a/imgdiag/imgdiag_test.cc b/imgdiag/imgdiag_test.cc index 3f2afc0696..0d46b2ea7a 100644 --- a/imgdiag/imgdiag_test.cc +++ b/imgdiag/imgdiag_test.cc @@ -24,6 +24,7 @@ #include "runtime/os.h" #include "runtime/arch/instruction_set.h" +#include "runtime/exec_utils.h" #include "runtime/utils.h" #include "runtime/gc/space/image_space.h" #include "runtime/gc/heap.h" diff --git a/oatdump/oatdump_test.cc b/oatdump/oatdump_test.cc index ba57d1860c..503cd4d581 100644 --- a/oatdump/oatdump_test.cc +++ b/oatdump/oatdump_test.cc @@ -24,6 +24,7 @@ #include "base/unix_file/fd_file.h" #include "runtime/arch/instruction_set.h" +#include "runtime/exec_utils.h" #include "runtime/gc/heap.h" #include "runtime/gc/space/image_space.h" #include "runtime/os.h" diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc index 2f40fef42e..a6c3cf067b 100644 --- a/profman/profile_assistant_test.cc +++ b/profman/profile_assistant_test.cc @@ -18,6 +18,7 @@ #include "base/unix_file/fd_file.h" #include "common_runtime_test.h" +#include "exec_utils.h" #include "profile_assistant.h" #include "jit/profile_compilation_info.h" #include "utils.h" diff --git a/runtime/Android.bp b/runtime/Android.bp index 5581810b4e..276f3043d9 100644 --- a/runtime/Android.bp +++ b/runtime/Android.bp @@ -57,6 +57,7 @@ cc_defaults { "dex_file_verifier.cc", "dex_instruction.cc", "elf_file.cc", + "exec_utils.cc", "fault_handler.cc", "gc/allocation_record.cc", "gc/allocator/dlmalloc.cc", diff --git a/runtime/dex2oat_environment_test.h b/runtime/dex2oat_environment_test.h index 7ae9f03c83..8b0c51c998 100644 --- a/runtime/dex2oat_environment_test.h +++ b/runtime/dex2oat_environment_test.h @@ -25,6 +25,7 @@ #include "common_runtime_test.h" #include "compiler_callbacks.h" +#include "exec_utils.h" #include "gc/heap.h" #include "gc/space/image_space.h" #include "oat_file_assistant.h" diff --git a/runtime/exec_utils.cc b/runtime/exec_utils.cc new file mode 100644 index 0000000000..9efb1a353c --- /dev/null +++ b/runtime/exec_utils.cc @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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 "exec_utils.h" + +#include <sys/types.h> +#include <sys/wait.h> +#include <string> +#include <vector> + +#include "android-base/stringprintf.h" +#include "android-base/strings.h" + +#include "runtime.h" + +namespace art { + +using android::base::StringAppendF; +using android::base::StringPrintf; + +int ExecAndReturnCode(std::vector<std::string>& arg_vector, std::string* error_msg) { + const std::string command_line(android::base::Join(arg_vector, ' ')); + CHECK_GE(arg_vector.size(), 1U) << command_line; + + // Convert the args to char pointers. + const char* program = arg_vector[0].c_str(); + std::vector<char*> args; + for (size_t i = 0; i < arg_vector.size(); ++i) { + const std::string& arg = arg_vector[i]; + char* arg_str = const_cast<char*>(arg.c_str()); + CHECK(arg_str != nullptr) << i; + args.push_back(arg_str); + } + args.push_back(nullptr); + + // fork and exec + pid_t pid = fork(); + if (pid == 0) { + // no allocation allowed between fork and exec + + // change process groups, so we don't get reaped by ProcessManager + setpgid(0, 0); + + // (b/30160149): protect subprocesses from modifications to LD_LIBRARY_PATH, etc. + // Use the snapshot of the environment from the time the runtime was created. + char** envp = (Runtime::Current() == nullptr) ? nullptr : Runtime::Current()->GetEnvSnapshot(); + if (envp == nullptr) { + execv(program, &args[0]); + } else { + execve(program, &args[0], envp); + } + PLOG(ERROR) << "Failed to execve(" << command_line << ")"; + // _exit to avoid atexit handlers in child. + _exit(1); + } else { + if (pid == -1) { + *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s", + command_line.c_str(), strerror(errno)); + return -1; + } + + // wait for subprocess to finish + int status = -1; + pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)); + if (got_pid != pid) { + *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: " + "wanted %d, got %d: %s", + command_line.c_str(), pid, got_pid, strerror(errno)); + return -1; + } + if (WIFEXITED(status)) { + return WEXITSTATUS(status); + } + return -1; + } +} + +bool Exec(std::vector<std::string>& arg_vector, std::string* error_msg) { + int status = ExecAndReturnCode(arg_vector, error_msg); + if (status != 0) { + const std::string command_line(android::base::Join(arg_vector, ' ')); + *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status", + command_line.c_str()); + return false; + } + return true; +} + +} // namespace art diff --git a/runtime/exec_utils.h b/runtime/exec_utils.h new file mode 100644 index 0000000000..093f7b8d80 --- /dev/null +++ b/runtime/exec_utils.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * 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. + */ + +#ifndef ART_RUNTIME_EXEC_UTILS_H_ +#define ART_RUNTIME_EXEC_UTILS_H_ + +#include <string> +#include <vector> + +namespace art { + +// Wrapper on fork/execv to run a command in a subprocess. +// Both of these spawn child processes using the environment as it was set when the single instance +// of the runtime (Runtime::Current()) was started. If no instance of the runtime was started, it +// will use the current environment settings. +bool Exec(std::vector<std::string>& arg_vector, std::string* error_msg); +int ExecAndReturnCode(std::vector<std::string>& arg_vector, std::string* error_msg); + +} // namespace art + +#endif // ART_RUNTIME_EXEC_UTILS_H_ diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index e03958d717..ffbca525d9 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -32,6 +32,7 @@ #include "base/scoped_flock.h" #include "base/systrace.h" #include "base/time_utils.h" +#include "exec_utils.h" #include "gc/accounting/space_bitmap-inl.h" #include "image-inl.h" #include "image_space_fs.h" diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc index 07d7b5a0f2..77cdd28d3a 100644 --- a/runtime/oat_file_assistant.cc +++ b/runtime/oat_file_assistant.cc @@ -25,6 +25,7 @@ #include "base/logging.h" #include "compiler_filter.h" #include "class_linker.h" +#include "exec_utils.h" #include "gc/heap.h" #include "gc/space/image_space.h" #include "image.h" diff --git a/runtime/utils.cc b/runtime/utils.cc index 80a427b1e7..6a20eaf9e0 100644 --- a/runtime/utils.cc +++ b/runtime/utils.cc @@ -929,74 +929,6 @@ std::string GetSystemImageFilename(const char* location, const InstructionSet is return filename; } -int ExecAndReturnCode(std::vector<std::string>& arg_vector, std::string* error_msg) { - const std::string command_line(android::base::Join(arg_vector, ' ')); - CHECK_GE(arg_vector.size(), 1U) << command_line; - - // Convert the args to char pointers. - const char* program = arg_vector[0].c_str(); - std::vector<char*> args; - for (size_t i = 0; i < arg_vector.size(); ++i) { - const std::string& arg = arg_vector[i]; - char* arg_str = const_cast<char*>(arg.c_str()); - CHECK(arg_str != nullptr) << i; - args.push_back(arg_str); - } - args.push_back(nullptr); - - // fork and exec - pid_t pid = fork(); - if (pid == 0) { - // no allocation allowed between fork and exec - - // change process groups, so we don't get reaped by ProcessManager - setpgid(0, 0); - - // (b/30160149): protect subprocesses from modifications to LD_LIBRARY_PATH, etc. - // Use the snapshot of the environment from the time the runtime was created. - char** envp = (Runtime::Current() == nullptr) ? nullptr : Runtime::Current()->GetEnvSnapshot(); - if (envp == nullptr) { - execv(program, &args[0]); - } else { - execve(program, &args[0], envp); - } - PLOG(ERROR) << "Failed to execve(" << command_line << ")"; - // _exit to avoid atexit handlers in child. - _exit(1); - } else { - if (pid == -1) { - *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s", - command_line.c_str(), strerror(errno)); - return -1; - } - - // wait for subprocess to finish - int status = -1; - pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)); - if (got_pid != pid) { - *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: " - "wanted %d, got %d: %s", - command_line.c_str(), pid, got_pid, strerror(errno)); - return -1; - } - if (WIFEXITED(status)) { - return WEXITSTATUS(status); - } - return -1; - } -} - -bool Exec(std::vector<std::string>& arg_vector, std::string* error_msg) { - int status = ExecAndReturnCode(arg_vector, error_msg); - if (status != 0) { - const std::string command_line(android::base::Join(arg_vector, ' ')); - *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status", - command_line.c_str()); - return false; - } - return true; -} - bool FileExists(const std::string& filename) { struct stat buffer; return stat(filename.c_str(), &buffer) == 0; diff --git a/runtime/utils.h b/runtime/utils.h index 5f53608f65..67438b5881 100644 --- a/runtime/utils.h +++ b/runtime/utils.h @@ -175,13 +175,6 @@ bool GetDalvikCacheFilename(const char* file_location, const char* cache_locatio // Returns the system location for an image std::string GetSystemImageFilename(const char* location, InstructionSet isa); -// Wrapper on fork/execv to run a command in a subprocess. -// Both of these spawn child processes using the environment as it was set when the single instance -// of the runtime (Runtime::Current()) was started. If no instance of the runtime was started, it -// will use the current environment settings. -bool Exec(std::vector<std::string>& arg_vector, std::string* error_msg); -int ExecAndReturnCode(std::vector<std::string>& arg_vector, std::string* error_msg); - // Returns true if the file exists. bool FileExists(const std::string& filename); bool FileExistsAndNotEmpty(const std::string& filename); diff --git a/runtime/utils_test.cc b/runtime/utils_test.cc index 82d92fc2fc..02f1e1bbfe 100644 --- a/runtime/utils_test.cc +++ b/runtime/utils_test.cc @@ -21,6 +21,7 @@ #include "base/enums.h" #include "class_linker-inl.h" #include "common_runtime_test.h" +#include "exec_utils.h" #include "mirror/array.h" #include "mirror/array-inl.h" #include "mirror/object-inl.h" |