diff options
Diffstat (limited to 'runtime/utils.cc')
| -rw-r--r-- | runtime/utils.cc | 147 |
1 files changed, 52 insertions, 95 deletions
diff --git a/runtime/utils.cc b/runtime/utils.cc index 8867743ec1..6a20eaf9e0 100644 --- a/runtime/utils.cc +++ b/runtime/utils.cc @@ -415,6 +415,22 @@ std::string PrintableString(const char* utf) { return result; } +std::string GetJniShortName(const std::string& class_descriptor, const std::string& method) { + // Remove the leading 'L' and trailing ';'... + std::string class_name(class_descriptor); + CHECK_EQ(class_name[0], 'L') << class_name; + CHECK_EQ(class_name[class_name.size() - 1], ';') << class_name; + class_name.erase(0, 1); + class_name.erase(class_name.size() - 1, 1); + + std::string short_name; + short_name += "Java_"; + short_name += MangleForJni(class_name); + short_name += "_"; + short_name += MangleForJni(method); + return short_name; +} + // See http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/design.html#wp615 for the full rules. std::string MangleForJni(const std::string& s) { std::string result; @@ -788,49 +804,58 @@ void GetTaskStats(pid_t tid, char* state, int* utime, int* stime, int* task_cpu) *task_cpu = strtoull(fields[36].c_str(), nullptr, 10); } -const char* GetAndroidRoot() { - const char* android_root = getenv("ANDROID_ROOT"); - if (android_root == nullptr) { - if (OS::DirectoryExists("/system")) { - android_root = "/system"; +static const char* GetAndroidDirSafe(const char* env_var, + const char* default_dir, + std::string* error_msg) { + const char* android_dir = getenv(env_var); + if (android_dir == nullptr) { + if (OS::DirectoryExists(default_dir)) { + android_dir = default_dir; } else { - LOG(FATAL) << "ANDROID_ROOT not set and /system does not exist"; - return ""; + *error_msg = StringPrintf("%s not set and %s does not exist", env_var, default_dir); + return nullptr; } } - if (!OS::DirectoryExists(android_root)) { - LOG(FATAL) << "Failed to find ANDROID_ROOT directory " << android_root; - return ""; + if (!OS::DirectoryExists(android_dir)) { + *error_msg = StringPrintf("Failed to find %s directory %s", env_var, android_dir); + return nullptr; } - return android_root; + return android_dir; } -const char* GetAndroidData() { +const char* GetAndroidDir(const char* env_var, const char* default_dir) { std::string error_msg; - const char* dir = GetAndroidDataSafe(&error_msg); + const char* dir = GetAndroidDirSafe(env_var, default_dir, &error_msg); if (dir != nullptr) { return dir; } else { LOG(FATAL) << error_msg; - return ""; + return nullptr; } } +const char* GetAndroidRoot() { + return GetAndroidDir("ANDROID_ROOT", "/system"); +} + +const char* GetAndroidRootSafe(std::string* error_msg) { + return GetAndroidDirSafe("ANDROID_ROOT", "/system", error_msg); +} + +const char* GetAndroidData() { + return GetAndroidDir("ANDROID_DATA", "/data"); +} + const char* GetAndroidDataSafe(std::string* error_msg) { - const char* android_data = getenv("ANDROID_DATA"); - if (android_data == nullptr) { - if (OS::DirectoryExists("/data")) { - android_data = "/data"; - } else { - *error_msg = "ANDROID_DATA not set and /data does not exist"; - return nullptr; - } - } - if (!OS::DirectoryExists(android_data)) { - *error_msg = StringPrintf("Failed to find ANDROID_DATA directory %s", android_data); - return nullptr; + return GetAndroidDirSafe("ANDROID_DATA", "/data", error_msg); +} + +std::string GetDefaultBootImageLocation(std::string* error_msg) { + const char* android_root = GetAndroidRootSafe(error_msg); + if (android_root == nullptr) { + return ""; } - return android_data; + return StringPrintf("%s/framework/boot.art", android_root); } void GetDalvikCache(const char* subdir, const bool create_if_absent, std::string* dalvik_cache, @@ -904,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; |