summaryrefslogtreecommitdiff
path: root/runtime/utils.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/utils.cc')
-rw-r--r--runtime/utils.cc147
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;